相关函数
- int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);初始化一个条件变量;也可以直接定义的方式初始化:pthread_cond_t cond = PTHREAD_COND_INITIALIZER(只能使用默认参数设定);
- int pthread_cond_broadcast(pthread_cond_t *cond); 发送一个信号到等待该条件变量的单个线程;
int pthread_cond_signal(pthread_cond_t *cond); 广播发送信号到所有等待该条件变量的线程;
- int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
等待该条件变量的信号,调用该函数会先解锁mutex并阻塞,所以在线程中先必须加锁;当等到信号时,就加锁mutex,唤醒线程;
- int pthread_cond_destroy(pthread_cond_t *cond); 销毁条件变量,前提是已经没有线程等待该条件变量;
条件变量示例
#include
#include
#include
#include
#include
#include
#include
#include
#define DBG_PRINT(fmt, args...) {printf("%s %d ", __FUNCTION__, __LINE__);printf(fmt,##args);}
#define DBG_LINE() {printf("%s %d\n", __FUNCTION__, __LINE__);}
typedef unsigned char BOOL;
#define TRUE 1
#define FALSE 0
/**
* [msDelay_select 用select()实现的ms级别线程休眠]
* @param msTime [休眠线程msTime时间,单位毫秒]
*/
void msDelay_select(unsigned msTime)
{
struct timeval time;
if(msTime == 0)
{
DBG_PRINT("delay time can not be 0!\n");
return;
}
if(msTime>=1000)
{
time.tv_sec = msTime/1000;
time.tv_usec = (unsigned long)(msTime%1000)*1000UL;
}
else
{
time.tv_sec = 0;
time.tv_usec = (unsigned long)msTime*1000UL;
}
select(0, NULL, NULL, NULL, &time);
}
static pthread_mutex_t mutexID;
static pthread_cond_t cond1ID, cond2ID;
static char testStr[1000];
BOOL mutexInit(void)
{
int ret = 0;
ret = pthread_mutex_init(&mutexID, NULL);
if(ret != 0)
{
DBG_PRINT("pthread_mutex_init failed! errno:%s\n", strerror(ret));
return FALSE;
}
return TRUE;
}
BOOL condInit(void)
{
int ret = 0;
ret = pthread_cond_init(&cond1ID, NULL);
if(ret != 0)
{
DBG_PRINT("pthread_cond_init failed! errno:%s\n", strerror(ret));
return FALSE;
}
ret = pthread_cond_init(&cond2ID, NULL);
if(ret != 0)
{
DBG_PRINT("pthread_cond_init failed! errno:%s\n", strerror(ret));
return FALSE;
}
return TRUE;
}
void *testThread1(void* arg)
{
int ret = -1;
while(1)
{
pthread_mutex_lock(&mutexID);
DBG_LINE();
/**
* pthread_cond_wait()会先尝试等待该条件变量,如果等不到,就解锁mutexID,然后线程进入阻塞;
* int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);是对应的设定超时等待的函数;
*/
ret = pthread_cond_wait(&cond1ID, &mutexID);
DBG_LINE();
DBG_PRINT("pthread_cond_wait:%s\n", strerror(ret));
DBG_PRINT("The string is:%s\n", testStr);
pthread_mutex_unlock(&mutexID);
}
return NULL;
}
void *testThread2(void* arg)
{
int ret = -1;
while(1)
{
pthread_mutex_lock(&mutexID);
DBG_LINE();
ret = pthread_cond_wait(&cond2ID, &mutexID);
DBG_LINE();
DBG_PRINT("pthread_cond_wait:%s\n", strerror(ret));
DBG_PRINT("The string is:%s\n", testStr);
pthread_mutex_unlock(&mutexID);
}
return NULL;
}
void *testThread3(void* arg)
{
int ret = -1;
while(1)
{
pthread_mutex_lock(&mutexID);
DBG_LINE();
ret = pthread_cond_wait(&cond2ID, &mutexID);
DBG_LINE();
DBG_PRINT("pthread_cond_wait:%s\n", strerror(ret));
DBG_PRINT("The string is:%s\n", testStr);
pthread_mutex_unlock(&mutexID);
}
return NULL;
}
int main(int argc, const char*argv[])
{
int ret = 0;
pthread_t thread1ID, thread2ID, thread3ID;
mutexInit();
condInit();
ret = pthread_create(&thread1ID, NULL, testThread1, NULL);
if(0 != ret)
{
DBG_PRINT("pthread_create failed, errno:%s\n", strerror(ret));
return -1;
}
ret = pthread_create(&thread2ID, NULL, testThread2, NULL);
if(0 != ret)
{
DBG_PRINT("pthread_create failed, errno:%s\n", strerror(ret));
return -1;
}
ret = pthread_create(&thread3ID, NULL, testThread3, NULL);
if(0 != ret)
{
DBG_PRINT("pthread_create failed, errno:%s\n", strerror(ret));
return -1;
}
pthread_detach(thread1ID);
pthread_detach(thread2ID);
pthread_detach(thread3ID);
DBG_LINE();
while(1)
{
pthread_mutex_lock(&mutexID);
DBG_LINE();
memset(testStr, 0x00, 1000);
fgets(testStr, 999, stdin);
if(0 == strncmp(testStr, "exit", 4))
{
pthread_mutex_unlock(&mutexID);
DBG_LINE();
return -1;
}
else if(0 == strncmp(testStr, "task1", 5))
{
DBG_LINE();
/**
* 发送信号到等待条件变量cond1ID的某一个线程;
*/
pthread_cond_signal(&cond1ID);
}
else if(0 == strncmp(testStr, "task2", 5))
{
DBG_LINE();
/**
* 发送信号到等待条件变量cond2ID的某一个线程;只会有一个线程解除阻塞,哪个线程先pthread_cond_wait,
* 就哪个线程先解除阻塞;
*/
pthread_cond_signal(&cond2ID);
}
else if(0 == strncmp(testStr,"broadcast", 9))
{
DBG_LINE();
/**
* 广播信号到等待条件变量cond2ID的所有线程,让等待cond2ID并且在阻塞中的所有线程重新获取mutex后运行;
*/
pthread_cond_broadcast(&cond2ID);
}
DBG_LINE();
pthread_mutex_unlock(&mutexID);
msDelay_select(200);
}
return 0;
}
编译运行,结果如下图: