条件变量
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
/* Compile like this:
 gcc --std=c99 -lpthread cond.c -o cond
*/
const size_t NUMTHREADS = 20;
/* a global count of the number of threads finished working. It will
   be protected by mutex and changes to it will be signalled to the
   main thread via cond */
int done = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/* Note: error checking on pthread_X calls ommitted for clarity - you
   should always check the return values in real code. */
/* Note: passing the thread id via a void pointer is cheap and easy,
 * but the code assumes pointers and long ints are the same size
 * (probably 64bits), which is a little hacky. */
void *ThreadEntry(void *id)
{
    const int myid = (long)id; // force the pointer to be a 64bit integer
    const int workloops = 5;
    for (int i = 0; i < workloops; i++)
    {
        printf("[thread %d] working (%d/%d)\n", myid, i, workloops);
        sleep(1); // simulate doing some costly work
    }
    // we're going to manipulate done and use the cond, so we need the mutex
    pthread_mutex_lock(&mutex);
    // increase the count of threads that have finished their work.
    done++;
    printf("[thread %d] done is now %d. Signalling cond.\n", myid, done);
    // wait up the main thread (if it is sleeping) to test the value of done
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    return NULL;
}
int main(int argc, char **argv)
{
    puts("[thread main] starting");
    pthread_t threads[NUMTHREADS];
    for (int t = 0; t < NUMTHREADS; t++)
        pthread_create(&threads[t], NULL, ThreadEntry, (void *)(long)t);
    // we're going to test "done" so we need the mutex for safety
    pthread_mutex_lock(&mutex);
    // are the other threads still busy?
    while (done < NUMTHREADS)
    {
        printf("[thread main] done is %d which is < %d so waiting on cond\n",
               done, (int)NUMTHREADS);
        // block this thread until another thread signals cond. While blocked, the mutex is released, then re-aquired before this thread is woken up and the call returns.
        pthread_cond_wait(&cond, &mutex);
        puts("[thread main] wake - cond was signalled.");
        /* we go around the loop with the lock held */
    }
    printf("[thread main] done == %d so everyone is done\n", (int)NUMTHREADS);
    pthread_mutex_unlock(&mutex);
    return 0;
}