线程安全:互斥与同步

线程安全

线程安全:多个执行流对同一临界资源进行争夺,但是不会造成数据二义或逻辑混乱

可重入: 同一个函数,多个执行流调用,一个执行流还没有结束,另一个执行流开始调用

不可重入:

  1. malloc/free函数
  2. 调用标准I/O库
  3. 函数体内有静态数据结构

函数可重入,线程安全
函数不可重入,多个线程调用,可能会引起线程安全问题
全局变量,即不可重入,也不线程安全

互斥

互斥:同一时间只能由一个线程能够访问临界资源
临界资源:多线程执行流共享的资源就叫做临界资源
临界区:每个线程内部,访问临界自娱的代码,就叫做临界区
原子性:不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成

写一个卖票的例子

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<pthread.h>
  4 
  5 int tickets = 100;
  6 
  7 void *GetTicket(void *args)
  8 {
  9     while(1)
 10     {
 11         if(tickets > 0)
 12         {
 13             usleep(1000000);
 14             printf("get a ticket ...%d\n", tickets--);
 15         }
 16         else
 17         {
 18             printf("%s... quit\n", (char*)args);
 19             break;
 20         }
 21     }
 22     pthread_exit((void*)0);
 23 }
 24 int main()
 25 {
 26     pthread_t tid1,tid2,tid3,tid4;
 27 
 28     pthread_create(&tid1, NULL, GetTicket, "thread 1");
 29     pthread_create(&tid2, NULL, GetTicket, "thread 2");
 30     pthread_create(&tid3, NULL, GetTicket, "thread 3");
 31     pthread_create(&tid4, NULL, GetTicket, "thread 4");
 32 
 33     pthread_join(tid1, NULL);
 34     pthread_join(tid2, NULL);
 35     pthread_join(tid3, NULL);
 36     pthread_join(tid4, NULL);
 37 
 38     return 0;
 39 }

在这里插入图片描述

如图产生了负数,这明显不合理,是因为tickets是临界资源,同时被四个线程所访问,因为- -操作不是原子性(因为冯诺依曼,++,–操作最少要经历三步,一从内存把数据拿到CPU中,二执行操作,三数据从CPU写回内存),有可能一个线程正在访问的时候,一个线程正在写入。所以要对临界资源加锁。

pthread_mutex_t lock; //创建锁
pthread_mutex_lock(&lock);//加锁 
pthread_mutex_unlock(&lock);//解锁
pthread_mutex_init(&lock, NULL);//初始化锁
pthread_mutex_destroy(&lock);//释放锁

在这里插入图片描述
互斥锁:
1. 互斥
2. 提供等待队列

同样的,一个线程要进行操作需要先得到锁,那么所有线程都会访问锁,锁也是临界资源,所以为了保证锁的原子性,大多数体系结构提供了swap或者exchange的汇编指令,由寄存器完成和内存的数据交换。

死锁:一组进程中各个进程均占有资源,但互相申请其他进程所占有的资源,且不释放自己的资源,相互等待。

条件:

  1. 互斥
  2. 请求与保持
  3. 不剥夺
  4. 循环等待

同步

通过条件判断实现对临界资源访问的合理性

详细会在我的另一篇博客中介绍:https://blog.csdn.net/weixin_43697119/article/details/103475885

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值