Pthread_join of one of a number of threads?

Most obvious, without restructuring your code as aix suggests, is to have each thread set something to indicate that it has finished (probably a value in an array shared between all threads, one slot per worker thread), and then signal a condition variable. Main thread waits on the condition variable and each time it wakes up, handle all threads that have indicated themselves finished: there may be more than one.

Most obvious, without restructuring your code as aix suggests, is to have each thread set something to indicate that it has finished (probably a value in an array shared between all threads, one slot per worker thread), and then signal a condition variable. Main thread waits on the condition variable and each time it wakes up, handle all threads that have indicated themselves finished: there may be more than one. Of course that means that if the thread is cancelled you never get signalled, so use a cancellation handler or don't cancel the thread.

Sounds good. But if a thread signals on a condition variable even before the main thread is waiting on it...say main thread creates 10 threads and thread 1 signals before thread 10 is created. – Juggler Sep 5 at 17:17 1 @Juggler: you need to use the condition variable correctly, I've left out the details but there are questions on SO how to do it or check a pthreads tutorial.

The main thread will (1) acquire the mutex, (2) check for anything to do and do it, (3) wait on the condvar, (4) go to 2. Workers will (1) acquire the mutex, (2) record that there's something to do, (3) signal the condvar, (4) release the mutex. – Steve Jessop Sep 5 at 17:20 Ahh...you are probably suggesting a thread pool kind of an implementation.

– Juggler Sep 6 at 4:44.

There are several ways to solve this. One natural way is to have a thread pool of fixed size n and have a queue into which the main thread would place tasks and from which the workers would pick up tasks and process them. This will maintain a constant degree of concurrency.An alternative is to have a semaphore with the initial value set to n.

Every time a worker thread is created, the value of the semaphore would need to be decremented. Whenever a worker is about to terminate, it would need to increment ("post") the semaphore. Now, waiting on the semaphore in the main thread will block until there's fewer than n workers left; a new worker thread would then be spawned and the wait resumed.

Since you won't be using pthread_join on the workers, they should be detached (pthread_detach).

If you want to be informed of a thread exiting (via pthread_exit or cancellation), you can use a handler with pthread_cleanup_push to inform the main thread of the child exiting (via a condition variable, semaphore or similar) so it can either wait on it, or simply start a new one (assuming the child is detached first). Alternately, I'd suggest having the threads wait for more work (as suggested by @aix), rather than ending.

If your parent thread needs to do other other things, then it can't just constantly be blocking on pthread_join, You will need a way to send a message to the main thread from the child thread to tell it to call pthread_join. There are a number of IPC mechanisms that you could use for this. When a child thread has done it's work, it would then send some sort of message to the main thread through IPC saying "I completed my job" and also pass its own thread id, then the main thread knows to call pthread_join on that thread id.

One easy way is to use a pipe as a communication channel between the (worker) threads and your main thread. When a thread terminates it writes its result (thread id in the following example) to the pipe. The main thread waits on the pipe and reads the thread result from it as soon as it becomes available.

Unlike mutex or semaphore, a pipe file descriptor can be easily handled by the application main event loop (such as libevent). The writes from different threads to the same pipe are atomic as long as they write PIPE_BUF or less bytes (4096 on my Linux). Below is a demo that creates ten threads each of which has a different life span.

Then the main thread waits for any thread to terminate and prints its thread id. It terminates when all ten threads have completed. $ cat test.Cc #include #include #include #include #include void* thread_fun(void* arg) { // do something unsigned delay = rand() % 10; usleep(delay * 1000000); // notify termination int* thread_completed_fd = static_cast(arg); pthread_t thread_id = pthread_self(); if(sizeof thread_id!

= write(*thread_completed_fd, &thread_id, sizeof thread_id)) abort(); return 0; } int main() { int fd2; if(pipe(fd)) abort(); enum { THREADS = 10 }; time_t start = time(NULL); // start threads for(int n = THREADS; n--;) { pthread_t thread_id; if(pthread_create(&thread_id, NULL, thread_fun, fd + 1)) abort(); std::cout Cc $ . /test 0 sec: started thread 140672287479552 0 sec: started thread 140672278759168 0 sec: started thread 140672270038784 0 sec: started thread 140672261318400 0 sec: started thread 140672252598016 0 sec: started thread 140672243877632 0 sec: started thread 140672235157248 0 sec: started thread 140672226436864 0 sec: started thread 140672217716480 0 sec: started thread 140672208996096 1 sec: thread 140672208996096 has completed 2 sec: thread 140672226436864 has completed 3 sec: thread 140672287479552 has completed 3 sec: thread 140672243877632 has completed 5 sec: thread 140672252598016 has completed 5 sec: thread 140672261318400 has completed 6 sec: thread 140672278759168 has completed 6 sec: thread 140672235157248 has completed 7 sec: thread 140672270038784 has completed 9 sec: thread 140672217716480 has completed.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions