linux下c编程条件变量

头文件 pthread.h

struct cangku 中定义了空间大小为7的 char 数组。读游标、写游标。非空、非满条件变量。互斥锁。

游标均采用从0 1 2 3 4 5 6 0 1 2...的移动方式。仓库初始化时,读、写游标被置零。条件变量使用函数

pthread_cond_init(&notempty,NULL)进行初始化。

本次示例代码中使用了消费者和生产者这个经典的问题。

首先创建消费者和生产者线程,分别对应的处理函数为consumerf、producerf

consumerf函数中,循环从仓库中取出字符显示在控制台上。在每次取字符之前,如果读、写游标重合,

此时仓库为空,那么消费者使用pthread_cond_wait(&notempty,&suo)等待生产者的利用pthread_cond_signal(&notempty)发出非空信号。

读出后将读游标按规则递增。读到z停止。

在producerf函数中,从a循环到z。如果写游标在读游标的前一个位置(按照递增规则),那么循环等待消费者产生的非满信号。

然后写入数据,写游标递增。

无论是消费者还是生产者,在每次执行操作之前,都需要添加互斥锁pthread_mutex_lock(&suo)。操作结束后执行pthread_mutex_unlock(&suo)解锁。

最后使用pthread_cond_destroy(&notempty)进行销毁。


注意事项:pthread_cond_wait(&notempty,&suo)函数需要用到互斥锁。pthread_cond_signal(&notempty)不需要锁。

#include <stdio.h>
#include <pthread.h>

struct cangku//仓库结构体
{
	char buf[7];
	int readpos;
	int writepos;
	pthread_cond_t notempty;//条件变量
 	pthread_cond_t notfull;
	pthread_mutex_t suo;
};

void initcangku(struct cangku *ck);
void destroyck(struct cangku *ck);
void consumerf(struct cangku *ck);
void producerf(struct cangku *ck);

int main()
{
	pthread_t consumer,producer;
	struct cangku ck;

	initcangku(&ck);
	pthread_create(&consumer,NULL,(void *)&consumerf,&ck);
	pthread_create(&producer,NULL,(void *)&producerf,&ck);
	pthread_join(producer,NULL);
	pthread_join(consumer,NULL);
        destroyck(&ck);
	return 0;
}

void initcangku(struct cangku *ck)
{
	ck->readpos = 0;
	ck->writepos = 0;
	pthread_cond_init(&ck->notempty,NULL);
	pthread_cond_init(&ck->notfull,NULL);
	pthread_mutex_init(&ck->suo,NULL);
}

void destroyck(struct cangku *ck)
{
	pthread_cond_destroy(&ck->notempty);
	pthread_cond_destroy(&ck->notfull);
	pthread_mutex_destroy(&ck->suo);
}

void consumerf(struct cangku *ck)
{
	while(1)
	{
		if(ck->buf[ck->readpos] == 'z')
			break;
		pthread_mutex_lock(&ck->suo);
		while(ck->readpos == ck->writepos)
		{
			pthread_cond_wait(&ck->notempty,&ck->suo);//deng dai tiao jian man zu
		}

		printf("consumer <- %c\n",ck->buf[ck->readpos]);
		ck->readpos++;
		if(ck->readpos == 7)
			ck->readpos = 0;
		pthread_cond_signal(&ck->notfull);
		pthread_mutex_unlock(&ck->suo);
	}
}

void producerf(struct cangku *ck)
{
	int i;
	for(i='a';i<='z';i++)
	{
		pthread_mutex_lock(&ck->suo);
		while((ck->writepos+1)%7 == ck->readpos)
		{
			pthread_cond_wait(&ck->notfull,&ck->suo);
		}
		ck->buf[ck->writepos] = i;
		printf("producer -> %c\n",i);
		ck->writepos++;
		if(ck->writepos == 7)
			ck->writepos = 0;

		pthread_cond_signal(&ck->notempty);
		pthread_mutex_unlock(&ck->suo);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值