条件变量:与互斥量一起使用,暂时申请不到某资源时进入条件阻塞等待,当资源具备时线程恢复运行
应用场合:生产线程不断的生产资源,并通知产生资源的条件,消费线程在没有资源情况下进入条件等待,一直等到条件信号的产生
主要函数有两个:
1)等待条件
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
2)发送条件信号
int pthread_cond_signal(pthread_cond_t *cond);
代码实例如下:
/** */
/****************************************************************
* 说明: Posix线程同步--条件变量实例
主线程生产消息--每一次从标准输入接收用户输入就生成一个消息,push到消息栈
线程1处理消息,从栈pop出来并打印
线程2处理消息,从栈pop出来并打印
试验线程1和线程2对pthread_cond_signal发出来的信号的接收情况
* 结论: pthread_cond_signal条件信号发送到哪个线程是不确定的,
线程A,线程B在申请不到某资源时,进入条件等待,当生产线程C产生资源时就发送条件信号,通知某进入条件等待的线程
假定是生产两个资源,然后AB线程各接收到条件信号,有可能线程A把两个资源全部消耗了,所以线程B在接收到条件信号时,
还是要再判断一次是否有资源可用。
根本原因在于发送条件信号(表示有资源可用)和接收条件信号之间有个时间差,这段时间内资源又没有了。
* 日期: 2008-3-19 14:17
*****************************************************************/
#include < malloc.h >
#include < stdio.h >
#include < pthread.h >
#include < stdlib.h >
struct msg ... {
char val;
struct msg* next;
} ;
/**/ /* 指向栈顶 */
struct msg * head = NULL;
pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;
void * thread1( void * arg)
... {
printf("thread(%d) begin ",pthread_self());
while(1)
...{
pthread_mutex_lock(&g_mutex);
/**//* 这里用while 和if是有区别的*/
while(head == NULL)
...{
printf("thread(%d):head is null ,fall sleep,waiting conditon signal ",pthread_self());
/**//* 发送条件信号和接收条件信号之间有个时间差,这段时间内head有可能再次为空,所以前面只能用while*/
pthread_cond_wait(&g_cond,&g_mutex);
printf("thread(%d):get conditon signal or aweek by itself ",pthread_self());
}
printf("thread(%d):get a msg, the value is %c ",pthread_self(),head->val);
head = head->next;
pthread_mutex_unlock(&g_mutex);
}
}
int main( void )
... {
pthread_t tid1,tid2;
printf("main thread begin ");
pthread_create(&tid1,NULL,thread1,NULL);
pthread_create(&tid2,NULL,thread1,NULL);
char c;
struct msg * new_msg;
while(1)
...{
c = getchar();
if(c==' ' ||c==' ')
continue;
new_msg = (struct msg*)malloc(sizeof(struct msg));
new_msg->val = c;
pthread_mutex_lock(&g_mutex);
/**//* 栈是空的*/
if(head == NULL)
...{
head = new_msg;
}else
...{
/**//* 栈非空,新消息入栈*/
new_msg->next = head;
head = new_msg;
}
//pthread_cond_signal(&g_cond);
pthread_cond_broadcast(&g_cond);
pthread_mutex_unlock(&g_mutex);
}
printf("main thread exit ");
return 0;
}
* 说明: Posix线程同步--条件变量实例
主线程生产消息--每一次从标准输入接收用户输入就生成一个消息,push到消息栈
线程1处理消息,从栈pop出来并打印
线程2处理消息,从栈pop出来并打印
试验线程1和线程2对pthread_cond_signal发出来的信号的接收情况
* 结论: pthread_cond_signal条件信号发送到哪个线程是不确定的,
线程A,线程B在申请不到某资源时,进入条件等待,当生产线程C产生资源时就发送条件信号,通知某进入条件等待的线程
假定是生产两个资源,然后AB线程各接收到条件信号,有可能线程A把两个资源全部消耗了,所以线程B在接收到条件信号时,
还是要再判断一次是否有资源可用。
根本原因在于发送条件信号(表示有资源可用)和接收条件信号之间有个时间差,这段时间内资源又没有了。
* 日期: 2008-3-19 14:17
*****************************************************************/
#include < malloc.h >
#include < stdio.h >
#include < pthread.h >
#include < stdlib.h >
struct msg ... {
char val;
struct msg* next;
} ;
/**/ /* 指向栈顶 */
struct msg * head = NULL;
pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;
void * thread1( void * arg)
... {
printf("thread(%d) begin ",pthread_self());
while(1)
...{
pthread_mutex_lock(&g_mutex);
/**//* 这里用while 和if是有区别的*/
while(head == NULL)
...{
printf("thread(%d):head is null ,fall sleep,waiting conditon signal ",pthread_self());
/**//* 发送条件信号和接收条件信号之间有个时间差,这段时间内head有可能再次为空,所以前面只能用while*/
pthread_cond_wait(&g_cond,&g_mutex);
printf("thread(%d):get conditon signal or aweek by itself ",pthread_self());
}
printf("thread(%d):get a msg, the value is %c ",pthread_self(),head->val);
head = head->next;
pthread_mutex_unlock(&g_mutex);
}
}
int main( void )
... {
pthread_t tid1,tid2;
printf("main thread begin ");
pthread_create(&tid1,NULL,thread1,NULL);
pthread_create(&tid2,NULL,thread1,NULL);
char c;
struct msg * new_msg;
while(1)
...{
c = getchar();
if(c==' ' ||c==' ')
continue;
new_msg = (struct msg*)malloc(sizeof(struct msg));
new_msg->val = c;
pthread_mutex_lock(&g_mutex);
/**//* 栈是空的*/
if(head == NULL)
...{
head = new_msg;
}else
...{
/**//* 栈非空,新消息入栈*/
new_msg->next = head;
head = new_msg;
}
//pthread_cond_signal(&g_cond);
pthread_cond_broadcast(&g_cond);
pthread_mutex_unlock(&g_mutex);
}
printf("main thread exit ");
return 0;
}