I'm testing the behavior of running concurrent threads in C, with a thread function that runs infinitely. My question is why doesn't, in the below code, "HELLO!!!" gets printed? I thought pthread_create() is called and then immediately it goes to the next iteration of the loop, why is the code waiting for the 1st pthread_create() to finish? Aren't multiple threads supposed to be running concurrently?
void main(int argc, char **argv)
{
pthread_t tid;
int i;
//Create 4 inf threads
for (i=0;i< 4;i++)
{
//printf("hello!\n");
//pthread_create(&tid, NULL, thread_incr, (void *)i);
pthread_create(&tid, NULL, t_nostop, (void *)i);
printf("HELLO!!!"); //This linen is NEVER printed!!
}
pthread_exit(NULL);
}
void* t_nostop(void * argp)
{
int i=1;
int t_num=(int) argp;
while(i==1){t_num++;}
}
Multiple threads are supposed to run concurrently. This should be happening in your code.
I'd guess that the printf calls are executed but don't generate output immediately. Console output may be line buffered, so will only be displayed when you print a newline or flush.
Try either adding \n at the end of the string you print or adding fflush(stdout) after the printf.
Edit: A comment asked about line buffering...
Line buffering happens when the standard C library decides that console writes are relatively expensive and should only be attempted for coherent blocks of text. One easy definition for a coherent block is a line. While it is waiting for a newline to be entered, the C lib stores the contents of printf calls in a block of memory, appending subsequent printfs
From my understanding on pthreads, you haven't actually started the thread yet. Try, after the pthread_create, adding pthread_join(tid, NULL); and see if it works.
Related
I have the following program that spawns two threads to print_something() and they both repeatedly print a specific string: thread 1 prints "Hi\n" and thread 2 prints "Bye\n":
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_something(int *k)
{
int n = 100;
int i;
if (*k) {
for (i = 0; i < 100; i++) {
printf("Hi\n");
}
} else {
for (i = 0; i < 100; i++) {
printf("Bye\n");
}
}
}
int main()
{
int x = 1, y = 0;
pthread_t t1, t2;
pthread_create(&t1, NULL, print_something, &x);
pthread_create(&t2, NULL, print_something, &y);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("End of program.\n");
return 0;
}
I expected them to run synchronously wherein the output in the terminal would be random such as:
Hi
Hi
Bye
Hi
Bye
...
But instead I always get thread 1 to finish its printing first before thread 2 will start printing:
Hi
Hi
...
Hi
Hi
Bye
Bye
...
Bye
Bye
End of program.
Why is the first thread blocking the second thread from printing?
Why is the first thread blocking the second thread from printing?
Who says it's blocking? Maybe starting a new thread takes long enough that the first additional thread (running in parallel with the original thread) finishes its printing (to stdout's buffer) before the second additional thread arrives at the point of trying to print anything.
On the other hand, POSIX does specify that the stdio functions perform operations on streams as if there was a lock associated with each stream that a thread must obtain upon entry to the function and releases upon exit. Thus, the first thread may indeed be blocking the second via the lock associated with stdout.
Moreover, when a thread unlocks a lock and then immediately tries to re-acquire the same lock, there is a high probability for that thread to succeed immediately despite other threads contending for the lock. As a result, when an entire loop body starts with acquiring a lock and ends with releasing that lock -- as is the case in your code for the lock associated stdout -- it is common for one thread to be able to monopolize the lock for many loop iterations.
I expected them to run synchronously wherein the output in the terminal would be random such as:
That's an unreasonable expectation. If two people each need to put in a hundred screws and are sharing a screwdriver, do you think they should hand off the screwdriver after each screw? It only makes sense to hand off the screwdriver when the one holding the screwdriver is tired.
Each thread spends the vast majority of its time accessing the console output stream. It can only do this by excluding the other thread. The behavior you expect would be atrocious.
Would they run on the same core? That would require a context switch after every line of output -- the worst performance possible for this code. Would they run on two cores? That would mean each core is waiting for the other core to finish with the console for about half the time -- also horrible performance.
Simply put, you expected your system to find a terrible way to do what you asked it to do. It found a much more efficient way -- letting one thread keep the console, finish what it was doing, and then letting the other go.
I am learning the basics of POSIX threads. I want to create a program that prints "Hello World!" 10 times with a delay of a second between each printout. I've used a for loop to print it 10 times, but I am stuck on how to implement the time delay part.
This is my code so far:
#define MAX 10
void* helloFunc(void* tid)
{
printf("Hello World!\n", (int)(intptr_t)tid);
}
int main(int ac, char * argv)
{
pthread_t hej[MAX];
for (int i = 0; i < MAX; i++)
{
pthread_create(&hej[i], NULL, helloFunc, (void*)(intptr_t)i);
pthread_join(&hej[i], NULL);
}
pthread_exit(NULL);
return(0);
}
Thanks in advance!
There are two major problems with your code:
First of all you must wait for the threads to finish. You do that by joining them with pthread_join. And for that to work you must save the pthread_t value from each and every thread (for example in an array).
If you don't wait for the threads then the exit call will end the process, and that will also unexpectedly kill and end all threads in the process.
For all threads to run in parallel you should wait in a separate loop after you have created them:
pthread_t hej[MAX];
for (int i = 0; i < MAX; i++)
{
pthread_create(&hej[i], ...);
}
for (int i = 0; i < MAX; i++)
{
pthread_join(&hej[i], NULL);
}
The second problem is that you pass a pointer to i to the thread, so tid inside the thread functions will be all be the same (and a very large and weird value). To pass a value you must first cast it to intptr_t and then to void *:
pthread_create(..., (void *) (intptr_t) i);
And in the thread function you do the opposite casting:
printf("Hello World %d!\n", (int) (intptr_t) tid);
Note that this is an exception to the rule that one should never pass values as pointers (or opposite).
Finally for the "delay" bit... On POSIX systems there are many ways to delay execution, or to sleep. The natural and simple solution would be to use sleep(1) which sleeps one second.
The problem is where do to this sleep(1) call. If you do it in the thread functions after the printf then all threads will race to print the message and then all will sleep at the same time.
If you do it in the loop where you create the threads, then the threads won't really run in parallel, but really in serial where one thread prints it message and exits, then the main thread will wait one second before creating the next thread. It makes the threads kind of useless.
As a possible third solution, use the value passed to the thread function to use as the sleep time, so the thread that is created first (when i == 0) will primt immediately, the second thread (when i == 1) will sleep one second. And so on, until the tenth thread is created and will sleep nine seconds before printing the message.
Could be done as:
void* helloFunc(void* tid)
{
int value = (int) (intptr_t) tid;
sleep(value);
printf("Hello World %d!\n", value);
// Must return a value, as the function is declared as such
return NULL;
}
I wrote the following code:
#include <pthread.h>
#include <stdio.h>
void* sayHello (void *x){
printf ("Hello, this is %d\n", (int)pthread_self());
return NULL;
}
int main (){
pthread_t thread;
pthread_create (&thread, NULL, &sayHello, NULL);
printf("HERE\n");
return 0;
}
After compiling and running I saw 3 different types of outputs.
Only "Here" was printed.
"Here" and 1 'sayHello' message.
"Here" and 2 'sayHello' messages.
Of course I'm OK with the second option, but I don't understand why the 'sayHello' massege can be printed 0 or 2 times if I created only one thread?
You can't say when the thread starts to run, it might not start until
after you return from main which means the process will end and the thread with it.
You have to wait for the thread to finish, with pthread_join, before leaving main.
The third case, with the message from the thread printed twice, might be because the thread executes, and the buffer is written to stdout as part of the end-of-line flush, but then the thread is preempted before the flush is finished, and then the process exist which means all file streams (like stdout) are flushed so the text is printed again.
For output 1:
your main function only create a pthread, and let it run without waiting for it to finish.
When your main function return, Operating system will collect back all the resources assigned to the pprocess. However the newly created pthread might have not run.
That is why you only got HERE.
For output 2:
your newly created thread finished before main function return. Therefore you can see both the main thread, and the created thread's output.
For output 3
This should be a bug in glibc. Please refer to Unexpected output in a multithreaded program for details.
To make the program always has the same output
pthread_join is needed after pthread_create
When you create a thread does it automatically start the thread function that's in the parameter?
I'm using
iret1 = pthread_create(&client[i++].tID, NULL, thread_function, NULL);
printf("Thread Created"); //for testing purposes
In my thread function I have a print statement at the very top. ex:
void *thread_function(void *arg){
printf("Entered thread function");
...
}
Instead of printing Entered thread function it prints Thread Created right after
And it doesn't print Entered thread function until I start another thread, is there a reason for this?
You need at least to add a newline \n at the end of every printf(3) format function, and often to call fflush(3), e.g. add a call to fflush(NULL); after each of your two printf ...
Don't forget that <stdio.h> functions are buffered. See setvbuf(3) function and man page.
The reason why your output is not printed as soon as you want it to be is that it is staying in the buffer of stdout.
And you probably have no guarantee on the output. The individual characters might perhaps be intermixed. Read unlocked_stdio(3) and flockfile(3) for details.
You may want to read (several times) some pthread tutorial...
PS you could consider using directly the write(2) syscall (without using any <stdio.h> function).
There's a weird behavior in my threads:
void * foo(void * nic){
printf("foo");
}
void * threadF(void * pointer){
printf("1\n");
pthread_t threadT;
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_create(&threadT,NULL,&foo,(void*)NULL);
printf("2\n");
while (!feof(stdin)){
int id, in, out;
fscanf(stdin,"%d:%d:%d",&id,&in,&out);
}
}
int main(){
pthread_attr_t attr;
pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_t threadT;
pthread_create(&vlaknoVstupu,&attr,&threadF,(void*)&data);
pthread_join(threadT,NULL);
pthread_attr_destroy (&attr);
}
// I skipped irelevant parts of code...
the thing is that sometimes the output is 12foo, but usually just 12.
Then the function waits for input. I would expect it to be always 12foo. Do anybody know why are my expectations wrong?
Edit: when I type some input like 1:1:1, which results in going through the while cycle again, there is always the foo output.
Printf does not have a thread guarantee. You shouldn't just call two functions on the same thing from different threads unless it's explicitly guaranteed to be safe, either by the writer or because you wrote it yourself.
What you should do is store a buffer of string pointers, and use atomic operations to insert strings into this buffer, then printf all of them every so often, free the memory, set to null, or just use a lock if it's ok to make the child threads wait on the printf call.
What happens is that (on most implementations) stdin and stdout are tied together in one practical buffer. This is to allow something like:
printf("Input: ");
scanf("%d", &integer);
to work nicely, the inputted characters will appear after the printf text.
As soon as your scanf will grab the stdin, this will 'lock' that buffer, also preventing the stdout of your other thread to flush its data to the screen. Note that 'lock'. Does not necessarily mean real thread locks.
If you'd call the program from console, input something like 1:2:3, and hit enter, you'd see that foo will be displayed at the end.
Since there is no join call for thread foo, the program is probably ending before it runs.