Linux/UNIX系统编程手册---第30章线程同步之条件变量

通知状态的改变:条件变量

生产者消费者模型
满足条件:
1.不能向满缓冲区存产品
2.不能向空缓冲区取产品
3.每个时刻仅允许一个生产者或消费者存或取1个产品
设置3个信号量
full:放有产品的缓冲区数,初值为0,例子中是avail
empty:可供使用的缓冲区数,例子中是avail
mutex:互斥量,初值为1,表示各进程互斥进入临界区,保证任何时候只有一个进程使用缓冲区
转自b站

一、未使用条件变量的例子

#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;
}

在学习中进步,如有错误,请多多批评指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeAmmon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值