Reputation: 5213
I am getting back into using pthreads and the definition of pthread_join bothers me.
It says
"The pthread_join() function shall suspend execution of the calling thread until the target thread terminates, unless the target thread has already terminated. On return from a successful pthread_join() call with a non-NULL value_ptr argument, the value passed to pthread_exit() by the terminating thread shall be made available in the location referenced by value_ptr. When a pthread_join() returns successfully, the target thread has been terminated. The results of multiple simultaneous calls to pthread_join() specifying the same target thread are undefined. If the thread calling pthread_join() is canceled, then the target thread shall not be detached."
I am trying to understand how, if I call pthread_join for one thread, then call pthread_join to start a second thread, the two threads are started, even though I imagine, the second pthread_join cannot be called because the first join has suspended the main thread from executing, and running the next line until pthread_exit is called from within the thread joined.
In particular, I imagine, the first pthread_join must wait until the specified thread has called pthread_exit, only then it should continue. However this is not the case, as I can do:
#include <pthread.h>
#include <stdio.h>
int avail = 0;
void *consumer(void *unused)
{
while (1) {
if (avail > 0) {
--avail;
puts("consumed");
}
}
}
void *producer(void *unused)
{
while (1) {
++avail;
puts("produced");
}
}
int main(int argc, char **argv)
{
pthread_t c_thread;
pthread_t p_thread;
pthread_create(&c_thread, 0, consumer, 0);
pthread_create(&p_thread, 0, producer, 0);
pthread_join(c_thread, 0);
pthread_join(p_thread, 0);
return 0;
}
ignoring the problem of possible race conditions to try to reduce code size, why are both the threads working, despite the first join suspending the main thread (thus, preventing the next join from being called, in my mind).
I would really like to understand how this works.
Thanks ahead of time.
Upvotes: 3
Views: 7571
Reputation: 5213
The threads do not start in pthread_join, but rather in pthread_create. I mislead myself into thinking pthread_join was used to actually start the thread, whereas it is a non-busy wait for the specific thread to return before the main thread continues it's execution, in my case, main returns before the threads get a chance to call the puts function.
The second pthread_join in my code is never actually called, because main is indeed suspended from the first pthread_join waiting on c_thread to return. The second join in this particular scenario is a "no operation" and the program never actually gets to it because consumer never actually returns.
Upvotes: 0
Reputation: 44181
Threads run concurrently, starting sometime during or after the call to pthread_create
. Calling pthread_join
has nothing to do with starting or running the thread, it simply waits until it exits. Both your threads have already been running and are still runnable at the point you enter and block on the first join and they will continue to run. The only thing blocked by the first join is your main thread.
Upvotes: 5