线程同步—互斥锁+条件变量

  在《线程同步—互斥锁》一文中,我们分析了只用互斥锁同步线程的弊端——CPU的效率和时效性不可兼得。下面,我们通过使用条件变量,在保证CPU效率的前提下,提高程序的时效性。

  只用互斥锁同步线程,其CPU占用率之所以高,是因为线程需要轮询,即需要不停的检查条件是否满足。我们使用条件变量,当条件不满足时,使线程阻塞。一旦条件满足,就会解除阻塞,继续往下执行。这样,线程就不需要轮询了,因此不需要占用太多CPU资源,而且具有很高的及时性。

  当条件满足时,可以唤醒单个阻塞的线程,也可以唤醒多个线程。注释掉的代码段,是唤醒多个线程的。代码如下:

#include
   
   
    
    
#include
    
    
     
     

char buffer[128];
int buffer_has_data=0;
pthread_mutex_t mutex;//锁定标志 
pthread_cond_t cond;//唤醒条件变量

void write_buffer(char *data)
{
	pthread_mutex_lock(&mutex);//锁定
	if(buffer_has_data==0)
	{
		sprintf(buffer,"%s",data);
		buffer_has_data=1;
		pthread_cond_signal(&cond);//当有数据可读时,唤醒单个线程
//		pthread_cond_broadcast(&cond);//唤醒所有线程,test1,test2
	}
	pthread_mutex_unlock(&mutex);//解锁
}

void read_buffer(void) 
{
	while(1)
	{
		pthread_mutex_lock(&mutex);//锁定, 阻塞前被锁上
               /*无数据时,一般用循环体阻塞。*/
		while(!buffer_has_data)
		{
			/*如果不满足被唤醒的条件,则释放互斥锁,阻塞在此处;
                          当唤醒的条件满足时,重新加锁,并解除阻塞。*/
			pthread_cond_wait(&cond,&mutex);
		}
		printf("read buffer,data = %s\n",buffer);
		buffer_has_data=0;
		pthread_mutex_unlock(&mutex);//解锁
	}
}
/*
void test1()
{
	while(1)
	{
		pthread_cond_wait(&cond,&mutex);//阻塞线程,等待唤醒
		printf("test1 run\n");
	}
	
}

void test2()
{
	while(1)
	{
		pthread_cond_wait(&cond,&mutex);//阻塞线程,等待唤醒
		printf("test2 run\n\n");
	}
}
*/

int main(int argc,char **argv)
{
	char input[128];
	pthread_t reader,t1,t2;
	
	pthread_mutex_init(&mutex,NULL);//生成互斥锁mutex,默认属性初始化
	pthread_cond_init(&cond,NULL);//生成一个唤醒变量,默认属性:同一进程内的所有线程使用.和外部的进程没有瓜葛,进程外部不可用
	
	pthread_create(&reader,NULL,(void*)(read_buffer),NULL);
//     pthread_create(&t1,NULL,(void*)(test1),NULL);//测试一次唤醒多个线程
//	pthread_create(&t2,NULL,(void*)(test2),NULL);//测试一次唤醒多个线程

	while(1)
	{
		scanf("%s",input);
		write_buffer(input);
	}
	
	pthread_join(reader,NULL);//等待线程退出
        pthread_join(t1,NULL);
	pthread_join(t2,NULL);
	pthread_cond_destroy(&cond);//释放阻塞唤醒变量
	pthread_mutex_destroy(&mutex);//释放互斥锁mutex资源	
	return 0;
}





    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值