I have question about exiting the while loop. I'm writing code in which I'm creating two threads, which prints strings and main() part has to print dots(".") every 500 miliseconds. Can you please help me how to exit the while loop after the second thread terminates, to get something like this on output:
...Hello...World....THE END
thank you for your help.
int main()
{
int mls = 0.5 ;
pthread_t thread1;
pthread_t thread2;
struktura param1 = { "Hello", 2};
struktura param2 = { "World", 4};
pthread_create( &thread1, NULL, thread, ¶m1);
pthread_create( &thread2, NULL, thread, ¶m2);
while(1)
{
printf(".");
fflush(stdout);
sleep(mls);
}
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("THE END\n");
return 0;
}
After having thought over the problem, I come to the conclusion that if the main use case is to really be sure both threads (thread "Hello" and thread "World") are gone there is no other way then to use pthread_join() on both.
As pthread_join() blocks the calling thread the natural conclusion is to start a third thread (thread "Dots") to draw the dots as requested.
This third thread (thread "Dots") then is signaled by the main()-thread waiting for the other two threads (thread "Hello" and thread "World") to finish after it returned from the two blocking call to pthread_join(). If this is done the third thread (thread "Dots") simply finishes. The latter could run detached, as no one is waiting for it to terminate.
while(pthread_kill(thread1, 0) == 0 && pthread_kill(thread2, 0) == 0)
{
printf(".");
fflush(stdout);
sleep(mls);
}
int pthread_kill(pthread_t thread, int sig);
You can use this function to retrieve status of the thread, if sig argument is 0, then no signal is sent, but error checking is still performed(eg. you can use this to check is thread 'alive').
It can return either 0 or error code(ESRCH - No thread with the ID thread could be found, and one more which is not important for this case), if returned value is 0 than thread is 'alive', if returned value is error code(ESRCH) than specified thread can't be found eg. it's 'dead'.
Try to use pthread_exit, as you can see in terminate c thread.
Related
#include <stdio.h>
#include <pthread.h>
void* thread(void *v) {
printf("The thread starts now\n");
//pthread_exit(NULL);
}
int main() {
int tid1;
int retValue = 0;
pthread_create(&tid1, NULL,thread, NULL);
retValue = pthread_join(tid1, NULL);
printf("Thread ID: %d, return value: %d\n",tid1, retValue);
retValue = pthread_join(tid1, NULL);
printf("Thread ID: %d, return value: %d\n",tid1, retValue);
return 0;
}
Sometimes the output is:
Thread ID: 1877241856, return value: 3
Thread ID: 1877241856, return value: 3
The thread starts now
Process finished with exit code 0
The question is:
By definition, pthread_join should block, wait for thread to finish executing, and then execute code that follows it. But why in my code, thread runs after the two pthread_join finish?
By definition, pthread_join returns 0 to indicate successful joining, but why the retValue of my code is always 3, whether thread runs before or after the pthread_join function?
There are a number of bugs in this code:
The first argument of pthread_create() should be a pthread_t, not an int. They are quite possibly not the same size, or otherwise interchangeable, so tid1 might not be a valid pthread id.
The thread does not return 0, or any other value for that matter. There is no return statement.
"On success, pthread_join() returns 0; on error, it returns an error number."
The thread's return value, if there was one, would be placed into the unused 2nd argument of pthread_join(). What is being treated as the return value is in fact the result of the pthread_join() call itself. Which is an error. Perhaps it is related to #1 above?
In addition to those found by TrentP worst bug of all is
Joining with a thread that has previously been joined results in undefined behavior.
i.e. calling pthread_join twice on the same thread
retValue = pthread_join(tid1, NULL);
retValue = pthread_join(tid1, NULL);
Is utterly wrong and saying it works if you change tid1 to pthread_t is wrong. The behaviour being undefined means that anything can happen when pthread_join is called the second time - pthread_join can return an error, pthread_join can return success, it can crash, it can hang, it can modify some other parts of memory, it can cause a new thread to be started...
I'm new to threading in C and was messing around in an attempt to learn about it. I compiled and executed the (very basic) code below:
void *thread(void *vargp);
int main(int argc, char **argv) {
pthread_t tid1, tid2;
printf("Hello from the main thread.\n");
printf("Creating thread 1.\n");
pthread_create(&tid1, NULL, thread, NULL);
printf("Creating thread 2.\n");
pthread_create(&tid2, NULL, thread, NULL);
printf("Main thread is going to wait on peer threads.\n");
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
printf("Peer threads have completed.\n");
return EXIT_SUCCESS;
}
void *thread(void *vargp) {
pthread_t tid = pthread_self();
printf("Hello from thread %u.\n", (unsigned int)tid);
return NULL;
}
I expected the output to be...
Hello from the main thread.
Creating thread 1.
Hello from thread [number].
Creating thread 2.
Hello from thread [number].
...
But instead, it was:
Hello from the main thread.
Creating thread 1.
Creating thread 2.
Main thread is going to wait on peer threads.
Hello from thread 3067947840.
Hello from thread 3076340544.
...
Why was the output in this order? Did the two threads wait until the join function to execute or did they just happen to take that long? Do threads need to be joined to the main thread in order to print output to the console?
Thanks for explaining this to me!!
You have only created threads 1 and 2 in order. But they'are necessarily executed in that order. The execution order is depends on how they're scheduled, number of processors available, etc.
So you could see the output from the two threads in any order.
If you would like to the output in "order", you could wait for first thread to complete before starting the next one.
printf("Creating thread 1.\n");
pthread_create(&tid1, NULL, thread, NULL);
pthread_join(tid1, NULL);
printf("Creating thread 2.\n");
pthread_create(&tid2, NULL, thread, NULL);
pthread_join(tid2, NULL);
This, of course, defeats the purpose of mutli-threading as only one thread ever does anything useful.
The ordering can be achieved in many ways. A simple way could be to use a semaphore.
I'm trying to understand how multithreading works. I've written the following code
`
void handler(void *arg)
{
printf("Printf from cleanup handler: %s\n", (char*)arg);
}
void print(const char *msg)
{
printf("%7s: Pid=%d Tid:%lu\n", msg, getpid(), pthread_self());
}
void* thread_function1(void *args)
{
printf("Received: %d\n", (int)args);
print("Thread");
pthread_cleanup_push(handler, "hello");
pthread_cleanup_pop(1);
printf("Thread Done\n");
return (void *) 0;
}
int main(void)
{
pthread_t tid1, tid2;
void *tret;
if(pthread_create(&tid1, NULL, thread_function1, (void *)1))
exit(1);
if(pthread_create(&tid2, NULL, thread_function1, (void *)2))
exit(1);
// pthread_join(tid2, &tret);
// pthread_join(tid1, &tret);
}
The problem with this code is that the main completes its execution before thread_function1 could complete its execution. If both the comments are removed then thread 2 is executed only after thread 1 has completeted its execution.
What I want to do is have thread 1 and thread 2 execute simultaneously and main should wait for completion of both the threads.
The problem with this code is that the main completes its execution before thread_function1 could complete its execution.
That's because when the main thread exits, the process dies including all threads. You can instead call pthread_exit(0) from the main thread so that the rest of the threads continue execution and the main thread exits.
If both the comments are removed then thread 2 is executed only after thread 1 has completeted its execution.
That's not true. i.e. tid1 and tid2 are executed simultaneously after they are created ("simultaneous execution" depends on your hardware, scheduling policy etc -- but as far as you program is concerned, they can be considered as being executed simultaneously). pthread_join() doesn't control the order of threads' execution. It only affects the order in which the main thread waits for the completion of the threads i.e. main thread waits for tid2 to complete first and then waits for tid1 (if you ncomment those two lines).
I'm having trouble understanding the pthread_join() function because of the results I am getting.
If pthread_join() is supposed to pause the calling thread until the thread of the given thread id finishes it's job then why does the following code not do Thread 1 work first then do Thread 2 work. They are both happening concurrently.
If I take out the two pthread_join() lines (from main) the program terminates and nothing happens. Does this mean the main thread is the calling process of both join functions and it is the main thread who is waiting for the other two newly created threads to finish?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *functionCount1();
void *functionCount2(void*);
int main()
{
/*
How to Compile
gcc -c foo
gcc -pthread -o foo foo.o
*/
printf("\n\n");
int rc;
pthread_t thread1, thread2;
/* Create two thread --I took out error checking for clarity*/
pthread_create( &thread1, NULL, &functionCount1, NULL)
pthread_create( &thread2, NULL, &functionCount2, &thread1)
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("\n\n");
exit(0);
}
void *functionCount1()
{
printf("\nFunction 1");
sleep(5);
printf("\nFunction 1");
return(NULL);
}
void *functionCount2(void* argument)
{
//pthread_t* threadID = (pthread_t*) argument;
//pthread_join(*threadID, NULL);
printf("\nFunction 2");
sleep(5);
printf("\nFunction 2");
return(NULL);
}
Output:
Output with sleep commented out:
Can someone explain why pthread_join is not doing what the documentation leads you to believe?
if pthread_join() is supposed to pause the calling process until the thread of the given thread id finishes it's job...
That is not quite correct: pthread_join() is supposed to pause the calling thread, not the calling process. Since you are calling pthread_join() from the thread running your main function, the other two threads are allowed to proceed concurrently, i.e. the way they do in your example.
The reason the code that you commented out does not work is that you are passing a pointer to pthread_t, but then you cast it to plain pthread_t inside the thread running function (i.e. pthread_t* becomes pthread_t). Fixing this problem should allow your code to produce the results that you expect:
void *functionCount2(void* argument)
{
pthread_t *threadID = (pthread_t*) argument;
pthread_join(*threadID, NULL);
printf("\nFunction 2");
sleep(5);
printf("\nFunction 2");
return(NULL);
}
In addition, you should remove pthread_join( thread1, NULL); from your main function, because the results of multiple simultaneous calls to pthread_join() specifying the same target thread are undefined.
I'm working on an application for Linux in C which uses multiple threads. The threads which are spawned by the main function do most of the work, and therefore usually finish last. I'm seeing some strange behavior, and I believe it's due to the main thread terminating before the spawned threads have a chance to finish their jobs. Here's some sample code to illustrate what I'm talking about:
#define _POSIX_C_SOURCE 200112L
#define _ISOC99_SOURCE
#define __EXTENSIONS__
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
void
my_cleanup(void *arg)
{
printf("cleanup: %s\n", (char *)arg);
}
void *
thread_stuff(void *arg)
{
printf("thread started\n");
pthread_cleanup_push(cleanup, "running");
if (arg)
pthread_exit((void *)2);
pthread_cleanup_pop(0);
pthread_exit((void *)2);
}
int
main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
return SUCCESS;
}
When this code is run, the message from the cleanup function is printed twice, as it should be, but other times when it is run, I see the message printed only once sometimes, and other times I see it printed three times or not at all. You add in the sleep function in the main function to play with how long it takes the main function to terminate.
What can I do to make the program run as it should? I suspect it has something to do with joining to the children, but I don't entirely understand the concept of a join or how to apply it to this situation.
Thanks in advance!
Yes, you should "join" the threads. "Joining" a thread simply means waiting until the thread has terminated. In other words, you would do
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
to wait until both threads have terminated.
Edit: What to do if you have a child thread which, in turn, creates a "grandchild" thread? As a rule, whoever created the thread should wait for it to terminate ("join" it). So in this scenario, the child thread would call phtread_join on the grandchild thread, and the main thread would call join on the child thread.
I think you want to run pthread_join on each of the threads when your main thread completes -- this makes the main thread stop until the given thread finishes running. Other threads can still complete first though, so running pthread_join on every thread will prevent the main thread from terminiating until all of the others have terminated.
There is a definite problem if main() finishes before the threads it spawned if you don't call pthread_exit() explicitly. All of the threads it created will terminate because main() is done and no longer exists to support the threads.
By having main() explicitly call pthread_exit() as the last thing it does, main() will block and be kept alive to support the threads it created until they are done.
int main()
{
int err;
pthread_t tid1, tid2;
err = pthread_create(&tid1, NULL, thread_stuff, (void *)1);
err = pthread_create(&tid2, NULL, thread_stuff, (void *)1);
sleep(10); /* change the value here if you want */
/* Add the pthread_exit */
pthread_exit(NULL);
return SUCCESS;
}
Refer for more info here