线程同步—互斥锁

  个人总结,请各位审慎的,批判着看。

  当两个线程访问共享数据时,可以用互斥锁来进行同步。先看一个例子:

  该程序有两个线程,一个用来从键盘读取输入的数据,一个把读取的数据显示出来。其中,数组buffer为两个线程的共享数据。

  编译:gcc mutex_pthread.c  -lpthread,不要忘记-lpthread

  运行该程序,在键盘上输入数据,然后把数据显示出来。读一个,写一个,如此循环。代码如下:

      

/* mutex_pthread.c*/

#include
   
   
    
    
#include
    
    
     
     

char buffer[128];
int buffer_has_data=0;//0:数据为空,可以写数据;1:数据不为空,可以读取数据。
pthread_mutex_t mutex;//锁定标志 

/*从键盘读取数据,并存储到buffer中*/
void write_buffer(char *data)
{
	pthread_mutex_lock(&mutex);
	/* 尝试加锁,如果该互斥锁已经被锁定了,则该函数将会阻塞,卡住不动,除非解锁,才会继续往下执行*/
	if(buffer_has_data==0)//判断数据是否被读取了
	{
		sprintf(buffer,"%s",data); //如果数据已经被读取,则写入新的数据
		buffer_has_data=1;
	}
	pthread_mutex_unlock(&mutex);//解锁
}

/*把buffer中的数据显示到屏幕中*/

void read_buffer(void)
{ 
     while(1) 
     { 
        pthread_mutex_lock(&mutex);
        if(buffer_has_data==1) 
        { 
           printf("read buffer,data = %s\n\n",buffer);
	   buffer_has_data=0; 
        } 
	pthread_mutex_unlock(&mutex);
        printf("子线程先运行,但是没有数据可读就解锁了\n");
        sleep(1);//该程序的不足之处
    }
}

int main(int argc, char **argv)
{
    char input[128];
    pthread_t reader;
    pthread_mutex_init(&mutex,NULL);//生成互斥锁mutex,用默认属性初始化一个互斥锁对象
    pthread_create(&reader,NULL,(void*)(read_buffer),NULL);//新建线程
    while(1)
   {
     scanf("%s",input);//从键盘获得数据
     write_buffer(input);
   }
 
   pthread_join(reader,NULL);
   pthread_mutex_destroy(&mutex);//释放互斥锁mutex资源
   return 0;
}
    
    
   
   

     执行完pthread_create(&reader,NULL,(void*)(read_buffer),NULL);之后,read_buffer()首先加锁。由于buffer_has_data=0,没有数据可读,该线程解锁。如果没有数据可读,则该线程一直不停的加锁,解锁。
  主线程执行完write_buffer(input);之后,也尝试加锁。待抢到锁之后,向buffer中写入数据,更新buffer_has_data的值,并释放锁,然后阻塞在scanf("%s",input);处,等待写入新的数据。
  这样,就能够对共享数据buffer进行精确的控制,保证写一次,读一次。
  该程序的缺陷:在read_buffer()中,需要不停的尝试加锁。
  如果注释掉sleep(1),当buffer中没有数据可读时,则该线程不停的加锁,解锁,一直循环,占用太多CPU资源。测试时发现,CPU利用率飙升的很高,这在实际应用中是不允许的。
  如果不注释掉sleep(1),则程序会有一个延时,实时性降低,也就是说CPU的利用率和时效性不可兼得。
  既然该程序的实时性较差,那么它是否一无是处呢?答案是否定的。在一些对实时性要求不高的场合,比如对温度的采集,可以使用该程序。
  如何使程序不占用太多的CPU资源,又能获得较高的实时性呢,我们可以使用条件变量。
  欲知条件变量为何物,请听下文分解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值