Blocking in pthread_join() - c

According to the manual page:
The pthread_join() function shall suspend execution of the calling
thread until the target thread terminates, unless the target thread
has already terminated.
So, as I understand, the calling process will block until the specified thread exit.
Now consider the following code:
pthread_t thrs[NUMTHREADS];
for (int i = 0; i < NUMTHREADS; i++)
{
pthread_create(&thrs[i], NULL, thread_main, NULL);
}
pthread_join(thrs[0], NULL); /* will be blocked here */
pthread_join(thrs[1], NULL);
pthread_join(thrs[2], NULL);
/* ... */
pthread_join(thrs[NUMTHREADS - 1], NULL);
The calling thread will be blocked in the call to pthread_join(thrs[0], NULL), until thrs[0] exit in some way. But how if another thread, for example, thrs[2] call pthread_exit() while we are blocked in the call to pthread_join(thrs[0], NULL)? Do we have to wait for thrs[0] to exit in order to receive the return value of thrs[2]?

But how if another thread, say thrs[2] exit while we are blocked in
the call to pthread_join(thrs[0], NULL)?
Yes, it could happen. In that case, pthread_join(thrs[2], NULL); will return immediately.
Do we have to wait for thrs[0] to exit in order to receive the return
value of thrs[2]?
Yes, you have to wait for thr[0] to terminate.
(Not directly related to the question)
It's not necessary to call pthread_join() on every thread you create. It's a convenient function to get the return status from thread(s). If you don't need to know the termination status of the thread, you could
create the thread by seeting the "detached" attribute or call pthread_detach(pthread_self()); from the thread itself to make it detached.
In some cases, you would want the threads created to continue execution but no longer need the main thread. In that case, you could call pthread_exit(NULL); from main thread which will let other threads to continue even after main thread exits.

Yes - the main thread blocked on thrs[0] will not get the result from thrs[2] until after thrs[[0] and thrs[1] have also exited.
If you need more flexibility one option is to do something like having the threads post their results in a queue or signal in some other way that the thread needs to be joined. The main thread can monitor that queue/signal and get the necessary results (which could come from a pthread_join() that is done on the thread that is known to be completed from information int he queue/signal).

Yes. The code is executed in serial.

Related

If main is a thread as well in c, why doesn't it run with other threads

I read that main() is single thread itself, so when i create 2 threads in my program like this;
#include<stdio.h>
#include<pthread.h>
#include<windows.h>
void* counting(void * arg){
int i = 0;
for(i; i < 50; i++){
printf("counting ... \n");
Sleep(100);
}
}
void* waiting(void * arg){
int i = 0;
for(i; i < 50; i++){
printf("waiting ... \n");
Sleep(100);
}
}
int main(){
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1, NULL, counting, NULL);
pthread_create(&thread2, NULL, waiting, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
int i = 0;
for(i; i < 50; i++){
printf("maining ... \n");
Sleep(1000);
}
}
Is main really a thread in that case?
in that case if in main in sleep for some time, shouldn't the main give the CPU to other threads?
Is main a threads itself here? I am confused a bit here.
Is there a specific order to main thread execution?
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
You asked the thread to wait until thread1 terminates and then wait until thread2 terminates, so that's what it does.
I read that main() is single thread itself
No, you have misunderstood. Every C program has a function named main(). C language semantics of the program start with the initial entry into that function. In that sense, and especially when you supply the parentheses, main(), is a function, not a thread.
However, every process also has a main thread which has a few properties that distinguish it from other threads. That is initially the only thread, so it is that thread that performs the initial entry into the main() function. But it is also that thread that runs all C functions called by main(), and by those functions, etc., so it is not, in general, specific to running only the code appearing directly in the body of main(), if that's what you mean by "main() is a single thread itself".
, so when i create 2 threads in my program like this; [...] Is main really a thread in that case?
There is really a main thread in that case, separate from the two additional threads that it starts.
in that case if in main in sleep for some time, shouldn't the main give the CPU to other threads?
If the main thread slept while either of the other two were alive, then yes, one would expect one or both of the others to get (more) CPU time. And in a sense, that's exactly what happens: the main thread calls pthread_join() on each of the other threads in turn, which causes it to wait (some would say "sleep") until those threads terminate before it proceeds. While it's waiting, it does not contend with the other threads for CPU time, as that's pretty much what "waiting" means. But by the time the main thread reaches the Sleep() call in your program, the other threads have already terminated and been joined, because that's what pthread_join() does. They no longer exist, so naturally they don't run during the Sleep().
Is main a threads itself here?
There is a main thread, yes, and it is the only one in your particular process that executes any of the code in function main(). Nothing gets executed except in some thread or other.
I am confused a bit here. Is there a specific order to main thread execution?
As already described, the main thread is initially the only thread. Many programs never have more than that one. Threads other than the main one are created only by the main thread or by another thread that has already been created. Of course, threads cannot run before they are created, nor, by definition, after they have terminated. Threads execute independently of each other, generally without any predefined order, except as is explicitly established via synchronization objects such as mutexes, via for-purpose functions such as pthread_join(), or via cooperative operations on various I/O objects such as pipes.
main() is not a thread but a function, so here's a clear "no" to your initial claim. However, if you read a few definitions of what is a thread, you will find that it is something that can be scheduled, i.e. an ongoing execution of code. Further, a running program will not be able to actually do anything without "ongoing execution of code" without e.g. main() as first entrypoint. So, definitely, every code executed by a program is executed by a thread, without exceptions.
BTW: You can retrieve the thread ID of the current thread. Try running that from main(). It will work and give you a value that distinguishes this call from calls from other threads.

What if thread exit before other thread wait for it(join)?

For example, If I create 3 threads and join them in the same order. If the second thread exit first, then what would happen to the pthread_join. Will the program block until tid1 exits or directly return from pthread_join(&tid2,NULL)?
pthread_t tid1,tid2,tid3;
pthread_create(&tid1, NULL, SomeFun, NULL);
pthread_create(&tid2, NULL, SomeFun, NULL);
pthread_create(&tid3, NULL, SomeFun, NULL);
pthread_join(&tid1, NULL);
pthread_join(&tid2, NULL);
pthread_join(&tid3, NULL);
when you code calls:
pthread_join(&tid1, NULL);
if tid1 has not exited yet, then that call will block until it does. if tid2 exits in the meantime, that doesn't change the behavior of this particular call. But in that scenario, when the call does return, the next call:
pthread_join(&tid2, NULL);
will return immediately since the tid2 has already exited.
If you want to immediately perform some work when an arbitrary thread is finished, you'll need to use something other than pthread_join() to synchronize with the "some thread is finished" event. Perhaps waiting on a condition variable that gets signaled by every thread when they complete (along with some mechanism such as a queue so the waiting thread can determine which thread has signaled completion). Another mechanism that could be used is to have threads write information to a pipe that the main (or controlling) thread reads to get that notification.
If you join a thread that has already ended, pthread_join will return immediately (and destroy the thread object, like it normally does).

how does calling pthread_join multiple times work?

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.
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.
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.

Can't terminate the thread using pthread_exit

I cant terminate the thread, it keeps sending things even after I close the terminal...
void *RTPfun(void * client_addr);
int main(int argc, char *argv[])
{
pthread_t RTPthread;
pthread_create(&RTPthread, NULL, &RTPfun, (void*)client_addr);
...
...
pthread_exit(&RTPfun);
return 0;
}
void *RTPfun(void * client_addr)
{
...
...
return 0;
}
Can someone tell me what am I doing wrong?
Thanks!
pthread_exit kills your current thread.
Notice, that if you kill the main thread as you do, it does not terminate the process. Other threads keep running.
You probably want to use pthread_cancel.
More generally though, killing threads is a bad idea. Correct way is to ask your threads politely to terminate and wait till they do.
If you call exit() from main, it will terminate main thread with all other thread.
If you call the method pthread_exit() from your main it will terminate main thread and let other thread will run continuously.
In your case you are calling pthread_exit() from main so your main thread get terminated, and other thread running until thread gets finish the job.
To cancel thread Add Below in RTPfun and add pthread_cancel in main.
/* call this when you are not ready to cancel the thread */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
/* call this when you are ready to cancel the thread */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
Working sample code:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *RTPfun(void * client_addr);
int main(int argc, char *argv[])
{
pthread_t RTPthread;
int client_addr;
pthread_create(&RTPthread, NULL, &RTPfun, (void*)client_addr);
sleep(2);
pthread_cancel(RTPthread);
pthread_join(RTPthread, NULL);
return 0;
}
void *RTPfun(void * client_addr)
{
int count = 0;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
while(1) {
if(count > 10) {
printf("thread set for cancel\n");
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
}
sleep(1);
printf("count:%d\n", count);
count ++;
}
return 0;
}
Used sleep in code for just understanding.
My understanding:
From "man pthread_exit" clearly talks about the description and rational behavior.
we will need to clean-up all respected resource that are been used in the thread created.
" The pthread_exit() function shall terminate the calling thread and make the value value_ptr available to any successful join with the terminating thread."
we shall pass "value_ptr" to exit(value_ptr) --> this will help to analyse what was the results of exit process.
obviously exit() - call exiting from the process, will release resources that used for.
In other way, you can create pthread in detached state, this attribute will reclaim the resources implicitly when pthread_exit . Refer "man pthread_detach".
We don't need to use pthread_join .. either go for pthread_detach again its simple go ahead set attribute .
/* set the thread detach state */
ret = pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_DETACHED);
Thanks.
Sankar
Your pthread_exit() exits the current thread. The parameter is used to pass a return value to any thread that then wants to join with it - and not to specify which thread to exit, as your code is implying.
The nicest way to do what you want is to use pthread_cancel() from your main thread. It takes the thread to cancel as a parameter, and then sends a cancellation request to that thread. Notice though, that by default cancellation is deferred, so your thread will keep on running until it hits a function that is a cancellation point - if you don't use any of those functions, you can insert an explicit cancellation point with a call to pthread_testcancel().
If you need to do some cleanup (for instance to free allocated memory, unlock mutexes, etc), you can insert a cleanup handler that is automatically called when canceling the thread. Have a look at pthread_cleanup_push() for this.
You can also set your thread to use asynchronous cancellation - your thread can then be canceled immediately, without hitting a cancellation point. However, asynchronous cancellation should only be used if you aren't using any system calls at all (that is, it's okay if you're purely doing calculations on already available data - but not if you're for instance using printf, file I/O, socket communication or similar), as otherwise you'll risk your system ending up in an inconsistent state.
After calling pthread_cancel(), your main thread should call pthread_join() on the canceled thread, to make sure all thread resources are cleaned up (unless you create the thread as detached).
You can of course also just have a shared doExit flag between the two threads, that the main thread can set, and which the other thread looks at from time to time. It's basically a manual way of using pthread_cancel().

terminating a thread in C

I a have a C program which calls to threads.
iret1 = pthread_create( &thread1, NULL, readdata, NULL);
iret2 = pthread_create( &thread2, NULL, timer_func, NULL);
pthread_join(thread2, NULL);
Thread 2 returns after performing some function, after which I want to stop the execution of thread 1. How should I do this?
You can stop the thread using pthread_cancel:
pthread_cancel(thread1);
And in readdata:
/* call this when you are not ready to cancel the thread */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
...
/* call this when you are ready to cancel the thread */
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
See the pthread_cancel man page for more information - there's an example included.
If you don't want to use pthread_cancel, you can use a global flag that is set by the main thread and read by thread 1. Also, you can use any of the IPC methods, like establishing a pipe between the threads.
You should signal to the thread that you wish it to stop work, and then wait for it to do so. For example, you could set a boolean flag that the thread tests regularly. If that flag indicates that work has been cancelled, then the thread should return from the thread function.
Don't attempt to forcibly terminate the thread from the outside because this will leave synchronisation objects in indeterminate state, lead to deadlocks etc.
Thread1 must have a flag which it verifies from time to time to see if it should abort itself.
There are ways to abort a thread from outside, but this is very dangerous. Don't.
Something like:
thread1stop=TRUE; //Thread 1 has access to this boolean value
pthread_join(thread1, NULL);
tkill(tid, SIGTERM) is the call you are looking for I do believe.
You can stop thread1 by calling pthread_cancel(thread1).
pthread_cancel() function sends a cancellation request to the thread.
After sending the request to cancel the thread you should check the return code to confirm that the thread was actually cancelled or not.
Here is a simple example:
rc = pthread_cancel(iret2);
if(rc) printf("failed to cancel the thread\n");
For further reference:
http://cursuri.cs.pub.ro/~apc/2003/resources/pthreads/uguide/users-39.htm
Other sources which might be useful to you.
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_create.3.html
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

Resources