0

What are the advantages of using pthread condition variables instead of pthread_join to emulate Windows WaitForMultipleObject?

Here is the C++ code to emulate Windows WaitForMultipleObject using pthread_join:

int i;
for(i=0;i<threads;i++)
    pthread_join(threadids[i], NULL);

Here is the C++ code to emulate Windows WaitForMultipleObject using pthread_cond_wait:

mCritSect.Lock(); 
pthread_mutex_lock(&mMutex);
while (true) {
    // check if ThreadPool array has unused element
    for (unsigned ix(0); ix < NumberThreads; ix++) {
        if (ThreadPool[ix] == 0) {

            pthread_create(pThread, 
                (const pthread_attr_t*)0, 
                (void(*)(void*))ThreadFunction                   
                ChildList);

            pthread_mutex_unlock(&mMutex);
            mCritSect.UnLock();
            return ThreadPool[ix];
        }
    }
    // wait on mConditionVariable for ThreadPool array element to become available
    pthread_cond_wait(&mConditionVariable, &mMutex); 
}   

Any help is greatly appreciated.

  • I will add more details later tonight or in the early morning. Thank you. – Francis Tuan Nov 02 '16 at 03:00
  • Those excerpts of code are not achieving the same thing. The first one is waiting until *every* thread in a set has finished, the second one is waiting for any single slot to become empty in an array and then starting a new thread, – caf Nov 02 '16 at 03:05
  • @caf, Thank you for your great comment. Could I ask you to comment on the polling associated with int i; for(i=0;i – Francis Tuan Nov 02 '16 at 03:17
  • There is no polling, `pthread_join()` is a blocking call. – caf Nov 02 '16 at 03:29
  • @caf, Could you read http://stackoverflow.com/questions/2821881/how-is-pthread-join-implemented? In particular, what David Schwartz said, The only really big difference between his code and the real code is that his code would cause the joining thread to burn 100% of the CPU if there's a spare core. – David Schwartz Could we email each other? Thank you – Frank Nov 02 '16 at 04:18
  • @Frank: That difference *is* the essential difference between polling and blocking. – caf Nov 02 '16 at 05:10
  • @caf, What does thread_yield do and how does the real code do the pthread_join()? – Frank Nov 02 '16 at 05:43
  • thread_yield() is just a made-up function for that example. The real code depends on the implementation - eg the NPTL glibc code on Linux uses a low-level wait operation called 'futex' to suspend the waiting thread until the waited-on thread terminates. The important point here is that `pthread_join()` suspends the calling thread until the waited-on thread finishes. – caf Nov 02 '16 at 06:11
  • @caf, Thank you for your answer. How does the real pthread_join() determine when the waited-on thread finishes? – Frank Nov 02 '16 at 06:17
  • It uses a kernel feature (the `clone(2)` flag `CLONE_CHILD_CLEARTID`). – caf Nov 02 '16 at 09:25
  • @caf, Thank you for your reply. I have two more questions for you. I will ask them in half an hour if it is okay with you. – Frank Nov 02 '16 at 10:27
  • @caf, Here are my two questions. What is the purpose of the clone(2) flag CLONE_CHILD_CLEARTID? Why might be the purpose of the critical section mCritSect in addition to the mutex lock mMutex? I will wait patiently. Thank you – Frank Nov 02 '16 at 12:06
  • @Does anyone else have an opinion about this? – Francis Tuan Nov 05 '16 at 02:42

0 Answers0