2 ms·
> This is almost never what you want. The most frequent case is to wait for the termination of anyone of a group of threads, which cannot be done with join. I
by spacechild1 5y ago
> This is almost never what you want. The most frequent case is to wait for the termination of anyone of a group of threads, which cannot be done with join.
I also have to say that this doesn't match my experience at all. Typically, my threads run for the whole duration of the program/object and I only need to join them when the program/object is done. In fact, this pattern is so common that C++20 added std::jthread which automatically joins the thread in the destructor.
I literally never had to wait for "the termination of anyone of a group of threads". For you it's apparently the most frequent case. This only teaches us not to make too broad assumptions. The world of programming is large.
- adrian_b 5y agoYour pattern is normal when you do not need to create a large number of threads. When you have enough work for a very large number of threads, there are 2 main styles to do it. Both styles avoid creating an excessive number of active threads in comparison with the number of available cores, because that can reduce the performance a lot. One style is to have a permanent pool of working threads and to use some means of communication between threads to know when any thread has finished its current job, to give a new piece of work to that thread. This is also done in the simplest way with some kind of waiting for any of multiple events in the dispatching thread, where the event is that some thread has signaled the end of its job. This style is appropriate for environments where thread creation and destruction is expensive, like Windows. When the thread creation and destruction is cheap and also the indvidual pieces of work are relatively large, requiring an execution time much greater than the thread creation/deletion time, a second style of programming is much simpler. You just create one thread for each piece of work, until you reach the limit for the maximum number of active threads. Then you wait until any thread terminates and then you create a new thread for the next piece of work. When there is no more work, you wait until all threads terminate. In conclusion, any kind of work where you could launch an arbitrarily high number of parallel threads needs to wait for any of a group of events. For all problems with limited parallelism, where you can create only few threads, you do not need this feature, but my work was always about problems where I could launch much more threads than the available hardware cores, where some kind of wait for multiple events is mandatory.