cond, condition (条件量),某个线程拿到 mutex,但发现某些条件没达到(比如队列中无任务),则需要 block,直到条件达到位置,此时 cond 就有作用了。
pthread_signal, 只唤醒所有等待 cond 线程中的一个。 pthread_broadcast, 唤醒所有等待 cond 的线程。其实还是一个个唤醒,一个被唤醒,释放 mutex,然后另一个被唤醒。 cond 典型的用法如下: pthread_mutex_lock(&m); while ( cond is not ok ) { pthread_cond_wait(&cond, &m); } ... do sth. pthread_mutex_unlock(&m); 为何这里需要一个 while 呢?因为 pthread_broadcast 会唤醒所有等待 cond 的线程,比如队列中只有一个任务,而唤醒了三个线程,则只有一个线程能拿到任务,而另两个需要继续 wait on cond。 cond 也有 process-shared 的属性,意义不大,忽略了。而 clock 属性是实时系统(realtime)才用的,略过不表。 ------------------------------ #include <stdio.h> #include <unistd.h> #include <time.h> #include <pthread.h> int global_val = 0; pthread_mutex_t global_mutex; pthread_cond_t global_cond; void *mythr(void *arg) { printf("thr #%d, before lock, time = %d\n", (int)arg, time(NULL)); pthread_mutex_lock(&global_mutex); while ( global_val > 0 ) { printf("thr #%d, before cond wait, time = %d\n", (int)arg, time(NULL)); pthread_cond_wait(&global_cond, &global_mutex); } global_val = 1; printf("thr #%d, cond, time = %d\n", (int)arg, time(NULL)); pthread_mutex_unlock(&global_mutex); return (void *)0; } int main() { pthread_t pid1, pid2, pid3, pid4; pthread_cond_init(&global_cond, NULL); pthread_mutex_init(&global_mutex, NULL); pthread_create(&pid1, NULL, mythr, (void *)1); pthread_create(&pid2, NULL, mythr, (void *)2); pthread_create(&pid3, NULL, mythr, (void *)3); pthread_create(&pid4, NULL, mythr, (void *)4); sleep(5); global_val = 0; pthread_cond_broadcast(&global_cond); sleep(5); global_val = 0; pthread_cond_signal(&global_cond); sleep(5); global_val = 0; pthread_cond_signal(&global_cond); pthread_join(pid1, NULL); pthread_join(pid2, NULL); pthread_join(pid3, NULL); pthread_join(pid4, NULL); return 0; } ------------------------------ $ ./a.out thr #1, before lock, time = 1262783837 thr #3, before lock, time = 1262783837 thr #4, before lock, time = 1262783837 thr #2, before lock, time = 1262783837 thr #3, cond, time = 1262783837 thr #4, before cond wait, time = 1262783837 thr #2, before cond wait, time = 1262783837 thr #1, before cond wait, time = 1262783837 // broadcast, all wakeup thr #4, cond, time = 1262783842 thr #2, before cond wait, time = 1262783842 thr #1, before cond wait, time = 1262783842 // signal, single wakeup thr #2, cond, time = 1262783847 thr #1, cond, time = 1262783852 ------------------------------ |
|