条件变量使我们可以睡眠等待某种条件出现。(windows下可以用互锁函数模拟linux下的条件变量)
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。
为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
条件变量类型为pthread_cond_
条件变量和互斥锁一样,都有静态动态两种创建方式:
静态方式使用PTHREAD_COND_INITIALIZER常量,如下: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,且被忽略。
注销一个条件变量需要调用pthread_cond_destroy(),只有在没有线程在该条件变量上等待的时候才能注销这个条件变量,否则返回EBUSY。API定义如下:int pthread_cond_destroy(pthread_cond_t *cond)
下面是鸟人从自己写的程序中摘出来的条件变量使用代码:
#include <stdlib.h> #include <queue> #include <pthread.h> struct InitIndexTask{ int x; int y; int z; InitIndexTask(int a, int b, int c) { this->x = a; this->y = b; this->z = c; } }; /****** *global variables ******/ const uint8_t THREAD_COUNT = 8; pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t condition_init = PTHREAD_COND_INITIALIZER; queue<InitIndexTask*> InitIndexQ; /****** *init thread body ******/ void* InitIndexThread(void* data) { char* thread_name = (char*)data; cout << "created an init_index_thread(tid:" << (unsigned int)pthread_self() << " tname:" << thread_name << ")." << endl; InitIndexTask* initTask = NULL; while (true){ pthread_mutex_lock( &init_mutex ); while (InitIndexQ.empty()) pthread_cond_wait( &condition_init, &init_mutex ); initTask = InitIndexQ.front(); InitIndexQ.pop(); pthread_mutex_unlock( &init_mutex ); if (!initTask) break; //... delete initTask; } cout << thread_name << " exited." << endl; delete[] BUFF; delete[] thread_name; } /****** * main ******/ int main(int argc, char** argv) { pthread_t* threadArr = new pthread_t[THREAD_COUNT]; for (uint8_t i = 0; i < THREAD_COUNT; ++i){ char* thread_name = new char[50]; snprintf(thread_name, 50, "Thread-%d", i); pthread_create(&threadArr[i], 0, &InitIndexThread, thread_name); } for (int i = 0; i < 100; i++) { InitIndexTask* task = new InitIndexTask(i, 2*i, 3*i); pthread_mutex_lock( &init_mutex ); InitIndexQ.push(task); pthread_mutex_unlock( &init_mutex ); pthread_cond_signal( &condition_init ); } for (uint8_t i = 0; i < THREAD_COUNT; ++i){ pthread_mutex_lock( &init_mutex ); InitIndexQ.push(NULL); pthread_mutex_unlock( &init_mutex ); pthread_cond_signal( &condition_init ); } for (uint8_t i = 0; i < THREAD_COUNT; ++i) pthread_join(threadArr[i], NULL); delete[] threadArr; cout << "main thread exited." << endl; }