条件变量使我们可以睡眠等待某种条件出现。(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;
}