3.7.6.线程同步之互斥锁 3.7.7.线程同步之条件变量

3.7.6.1、什么是互斥锁
(1)互斥锁又叫互斥量(mutex)
(2)相关函数:

                    pthread_mutex_init  初始化互斥锁

                    pthread_mutex_destroy 删除互斥锁


                    pthread_mutex_lock  互斥锁 上锁

                   pthread_mutex_unlock  互斥锁 解锁
(3)互斥锁和信号量的关系:可以认为互斥锁是一种特殊的信号量
(4)互斥锁主要用来实现关键段保护: 保证当前线程 访问时,不允许其他线程访问

注意:man  pthread_mutex_init时提示找不到函数,说明你没有安装pthread相关的man手册。安装方法:1、虚拟机上网;2、sudo apt-get install manpages-posix-dev


3.7.6.2、用互斥锁来实现上节的代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>




char buf[200] = {0};

pthread_mutex_t mutex;  /*  定义一个互斥锁 mutex */

int flag = 0;

//子线程程序,作用是统计 buf 的个数 和 显示
void *func(void *arg)
{
	// 子线程首先应该有个循环
	// 循环中阻塞在等待主线程激活的时候,子线程被激活后就去获取buf中的字符
	// 长度,然后打印;完成后再次被阻塞
	
	sleep(1);	
	
	while(flag == 0)
	{	
		pthread_mutex_lock(&mutex);	/* 互斥量 上锁 */

		printf("本次输入了%d个字符\n", strlen(buf));
		memset(buf, 0, sizeof(buf));
		
		pthread_mutex_unlock(&mutex);/* 互斥量 解锁 */	
		
		sleep(1);
	}
	printf("跳出 while死循环 \n");
	pthread_exit(NULL);  /*  退出子线程 */
	
}



int main()
{
	int ret =-1;
	pthread_t th = -1;
	
	/*初始化 互斥量  */
	pthread_mutex_init(&mutex, NULL);
	
	/* pthread_create 创建 子线程 */
	ret = pthread_create(&th,NULL,func, NULL);/* pthread_create 创建线程成功 返回0 */
	if(ret != 0)
	{
		printf("pthread_create error \n");
		exit(-1);
	}
	
	
	
	
	printf("输入一个字符串,以回车结束 \n");
	
	while(1)
	{
		
		pthread_mutex_lock(&mutex);/* 互斥量 上锁 */
		scanf("%s",buf);
		
		pthread_mutex_unlock(&mutex);/* 互斥量 解锁 */
		
		//去 比较 用户输入的是不是 end ,如果是 则退出,如果不是则继续
		if(!strncmp(buf, "end", 3))/*  strncmp :字符比较函数,如果相等 返回0 */
		{
			printf("程序结束 \n");
			flag = 1;
			
			break; /*  直接跳出 while 循环 */
		}
		sleep(1);
		// 主线程在收到用户收入的字符串,并且确认不是end后
		// 就去发信号激活子线程来计数。
		// 子线程被阻塞,主线程可以激活,这就是线程的同步问题。
		// 信号量就可以用来实现这个线程同步
			
		
	}
		
	
	
	
	printf("等待回收子线程\n");
	
	//回收子线程
	ret = pthread_join(th,NULL);
	if(ret != 0)
	{
		printf("pthread_join error \n");
		exit(-1);
	}
	
	printf("子线程回收成功\n");
	
	pthread_mutex_destroy(&mutex);  /*删除 互斥锁  */
	
	return 0;
}









运行结果:

  注意: 互斥锁 不是 阻塞的, 只是 上锁一次, 就要解锁 一次,

        我自己理解的!!!

3.7.7.线程同步之条件变量
3.7.7.1、什么是条件变量:  条件变量 跟 互斥锁 有关系的 ,
3.7.7.2、相关函数
   pthread_cond_init     初始化 条件变量

  pthread_cond_destroy  删除 条件变量

  pthread_cond_wait      等待 条件变量

 pthread_cond_signal/pthread_cond_broadcast  这两个都是 唤醒 条件变量

    signal: 只唤醒一个 条件变量

    broadcas: 广播    唤醒很多条件变量  

3.7.7.3、使用条件变量来实现上节代码  : 效率高 , 没有 sleep 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>




char buf[200] = {0};

pthread_mutex_t mutex;  /*  定义一个互斥锁 mutex */
pthread_cond_t cond;  /*  定义一个条件变量 cond */

int flag = 0;

//子线程程序,作用是统计 buf 的个数 和 显示
void *func(void *arg)
{
	// 子线程首先应该有个循环
	// 循环中阻塞在等待主线程激活的时候,子线程被激活后就去获取buf中的字符
	// 长度,然后打印;完成后再次被阻塞

	
	while(flag == 0)
	{	
		pthread_mutex_lock(&mutex);	/* 互斥量 上锁 */
		
		pthread_cond_wait(&cond, &mutex); /* 等待 条件变量 发信号, 必须要加 互斥锁 */

		printf("本次输入了%d个字符\n", strlen(buf));
		memset(buf, 0, sizeof(buf));
		
		pthread_mutex_unlock(&mutex);/* 互斥量 解锁 */	
		
	
	}
	printf("跳出 while死循环 \n");
	pthread_exit(NULL);  /*  退出子线程 */
	
}



int main()
{
	int ret =-1;
	pthread_t th = -1;
	
	/*初始化 互斥量  */
	pthread_mutex_init(&mutex, NULL);
	/*初始化 条件变量 cond  */
	pthread_cond_init(&cond, NULL);
	
	/* pthread_create 创建 子线程 */
	ret = pthread_create(&th,NULL,func, NULL);/* pthread_create 创建线程成功 返回0 */
	if(ret != 0)
	{
		printf("pthread_create error \n");
		exit(-1);
	}
	
	
	
	
	printf("输入一个字符串,以回车结束 \n");
	
	while(1)
	{
		
		//pthread_mutex_lock(&mutex);/* 互斥量 上锁 */
		scanf("%s",buf);
		pthread_cond_signal(&cond);
		//pthread_mutex_unlock(&mutex);/* 互斥量 解锁 */  
		
		//去 比较 用户输入的是不是 end ,如果是 则退出,如果不是则继续
		if(!strncmp(buf, "end", 3))/*  strncmp :字符比较函数,如果相等 返回0 */
		{
			printf("程序结束 \n");
			flag = 1;
			
			break; /*  直接跳出 while 循环 */
		}
		//sleep(1);
		// 主线程在收到用户收入的字符串,并且确认不是end后
		// 就去发信号激活子线程来计数。
		// 子线程被阻塞,主线程可以激活,这就是线程的同步问题。
		// 信号量就可以用来实现这个线程同步
			
		
	}
		
	
	
	
	printf("等待回收子线程\n");
	
	//回收子线程
	ret = pthread_join(th,NULL);
	if(ret != 0)
	{
		printf("pthread_join error \n");
		exit(-1);
	}
	
	printf("子线程回收成功\n");
	
	pthread_mutex_destroy(&mutex);  /*删除 互斥锁  */
	pthread_cond_destroy(&cond);  /*删除 条件变量  */
	return 0;
}


运行结果:

3.7.7.4、线程同步总结

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大漠飞鹰6666

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

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

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

打赏作者

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

抵扣说明:

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

余额充值