pthread_cond_wait
多线程的条件变量
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
创建和注销
pthread_cond_t cond=PTHREAD_COND_INITIALIZER
动态方式调用
pthread_cond_init()函数,API定义如下:
int
pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
尽管POSIX标准中为
条件变量定义了属性,但在LinuxThreads中没有实现,因此cond_attr值通常为NULL,且被忽略。
等待和激发
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
pthread_cond_signal()激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个
/* *主线程创建子线程(当前子线程为stop停止状态),5秒后主线程唤醒子线程, *10秒后主线程挂起子线程。15秒后主线程再次唤醒子线程,20秒后主线程执行完毕, *等待子线程退出。 */ #include <stdio.h> #include <string.h> #include <pthread.h> #define RUN 1 #define STOP 0 pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int status = STOP; void *thread_function(void) { static int i = 0; while(1) { pthread_mutex_lock(&mut); while(!status) { pthread_cond_wait(&cond, &mut); } pthread_mutex_unlock(&mut); printf("child pthread %d\n", i++); if (i == 20) { break; } sleep(1); } } void thread_resume() { if (status == STOP) { pthread_mutex_lock(&mut); status = RUN; pthread_cond_signal(&cond); printf("pthread run!\n"); pthread_mutex_unlock(&mut); } else { printf("pthread run already\n"); } } void thread_pause() { if (status == RUN) { pthread_mutex_lock(&mut); status = STOP; printf("thread stop!\n"); pthread_mutex_unlock(&mut); } else { printf("pthread pause already\n"); } } int main() { int err; static int i = 0; pthread_t child_thread; if (pthread_mutex_init(&mut, NULL) != 0) { printf("mutex init error\n"); } if (pthread_cond_init(&cond, NULL) != 0) { printf("cond init error\n"); } err = pthread_create(&child_thread,NULL,(void *)thread_function,NULL); if (err != 0) { printf("can't create thread:%s\n", strerror(err)); } while(1) { printf("father pthread %d\n", i++); sleep(1); if (i == 5) { thread_resume(); } if (i == 10) { thread_pause(); } if (i == 15) { thread_resume(); } if (i == 20) { break; } } if (0 == pthread_join(child_thread, NULL)) { printf("child thread is over\n"); } return 0; }