通知状态的改变:条件变量
生产者消费者模型
满足条件:
1.不能向满缓冲区存产品
2.不能向空缓冲区取产品
3.每个时刻仅允许一个生产者或消费者存或取1个产品
设置3个信号量
full:放有产品的缓冲区数,初值为0,例子中是avail
empty:可供使用的缓冲区数,例子中是avail
mutex:互斥量,初值为1,表示各进程互斥进入临界区,保证任何时候只有一个进程使用缓冲区
一、未使用条件变量的例子
#include <pthread.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<stdbool.h>
static int avail = 0;//放有产品的缓冲区数,初值为0
static pthread_mutex_t mxt = PTHREAD_MUTEX_INITIALIZER;
static void * threadFunc(void *arg)
{
int cnt = *((char *)arg);
int loc,j,s;
for(j = 0; j < cnt;j++){
sleep(1);
//生产者线程
s = pthread_mutex_lock(&mxt);
if (s != 0)
printf("s=%d,pthread1_mutex_lock is failed\n",s);
avail++;
s = pthread_mutex_unlock(&mxt);
if (s != 0)
printf("s=%d,pthread1_mutex_unlock is failed\n",s);
}
return NULL;
}
int main(int argc,char *argv[])
{
pthread_t t1;
int totRequired = 0,numConsumed = 0;
int s,j,loops;
time_t t;
bool done = false; //不生产
t = time(NULL);
for(j = 1;j<argc;j++){
totRequired += atoi(argv[j]);
printf("argc=%d,totRequired=%d\n",argc,totRequired);
s = pthread_create(&t1,NULL,threadFunc,argv[j]);//s返回0成功
if(s != 0)
printf("s=%d,pthread1_create is failed\n",s);
}
//主线程(消费者)
for(;;){
s = pthread_mutex_lock(&mxt);
if (s != 0)
printf("s=%d,main_pthread_mutex_lock is failed\n",s);
while (avail > 0){
numConsumed++;
avail--;
printf("T=%ld: numConsumed=%d\n", (long)(time(NULL) - t),
numConsumed);
done = numConsumed >= totRequired;
}
s = pthread_mutex_unlock(&mxt);
if (s != 0)
printf("s=%d,main_pthread_mutex_unlock is failed\n",s);
if(done)
break;
}
return 0;
}
二、使用条件变量的例子
#include <pthread.h>
//#include "tlpi_hdr.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<stdbool.h>
/**************************************
* gcc demo_30_1.c -lpthread -o demo_30_1
* ************************************/
/**********************************************
使用静态分配的条件变量的简单例子
* ***********************************/
//#define __USE_UNIX98
static int avail = 0;//放有产品的缓冲区数
static pthread_mutex_t mxt = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static void * threadFunc(void *arg)
{
int cnt = *((char *)arg);
int loc,j,s;
for(j = 0; j < cnt;j++){
sleep(1);
//生产者线程
s = pthread_mutex_lock(&mxt);
if (s != 0)
printf("s=%d,pthread1_mutex_lock is failed\n",s);
avail++;
s = pthread_mutex_unlock(&mxt);
if (s != 0)
printf("s=%d,pthread1_mutex_unlock is failed\n",s);
/******************************************************************
函数pthread_cond_signal()和pthread_cond_broadcast()均可针对由参数cond所指定的条件
变量而发送信号。pthread_cond_wait()函数将阻塞一线程,直至收到条件变量cond的通知.
pthread_cond_signal:只保证唤醒至少一条遭到阻塞的线程
pthread_cond_broadcast:会唤醒所有遭阻塞的线程
*******************************************************************/
s = pthread_cond_signal(&cond);
if (s != 0)
printf("s=%d,pthread_cond_signal is failed\n",s);
//printf("avail=%d,pthread_cond_signal enter\n",avail);
}
return NULL;
}
int main(int argc,char *argv[])
{
pthread_t t1;
int totRequired = 0,numConsumed = 0;
int s,j,loops;
time_t t;
bool done = false;
//Boolean done = FALSE;
t = time(NULL);
for(j = 1;j<argc;j++){
totRequired += atoi(argv[j]);
//printf("argc=%d,totRequired=%d\n",argc,totRequired);
s = pthread_create(&t1,NULL,threadFunc,argv[j]);//s返回0成功
if(s != 0)
printf("s=%d,pthread1_create is failed\n",s);
printf("pthread%d_create\n",j);
}
//主线程(消费者)
for(;;){
s = pthread_mutex_lock(&mxt);
if (s != 0)
printf("s=%d,main_pthread_mutex_lock is failed\n",s);
while (avail == 0)
{
s = pthread_cond_wait(&cond, &mxt);
if (s != 0)
printf("s=%d,pthread_cond_wait is failed\n",s);
printf("avail=%d,main_pthread_cond_wait\n",avail);
}
while (avail > 0){
numConsumed++;
avail--;
printf("T=%ld: numConsumed=%d\n", (long)(time(NULL) - t),
numConsumed);
done = numConsumed >= totRequired;
}
s = pthread_mutex_unlock(&mxt);
if (s != 0)
printf("s=%d,main_pthread_mutex_unlock is failed\n",s);
if(done)
break;
}
return 0;
}
在学习中进步,如有错误,请多多批评指正