linux线程安全

目录

什么是线程安全问题?

一.多线程抢票问题:

二.单核CUP上线程并发没有并行也会引发线程安全问题

线程安全问题的常见解决方案

一.互斥

互斥锁

1.为什么要有互斥锁?

2.互斥锁的使用

互斥锁创建和初始化

加锁

解锁

3.互斥锁的封装

4.互斥锁的原理

自旋锁

二.同步

同步和互斥的区别和联系

条件变量

信号量

多线程的生产消费模型


什么是线程安全问题?

线程安全问题是指在多线程环境下,当多个线程访问共享资源可能会导致的数据不一致问题。

一.多线程抢票问题:

以下面的多线程抢票代码为例:

#include<iostream>
#include<stdio.h>
using namespace std;
int tickets=10000;
void* threadroutine(void* arg)
{
  char* name=(char*)arg;
  while(true)
  {
    if(tickets>0)
    {
      cout<<name<<" get a ticket :"<<tickets<<endl;
      tickets--;
    }
    else
    break;
  }
  return nullptr;
}
int main()
{
  pthread_t tids[5];
  //创建线程
  for(int i=0;i<5;i++)
  {
    char name[32];
    sprintf(name,"%s%d","thread-",i+1);
    pthread_create(&tids[i],nullptr,threadroutine,(void*)name);
  }
  //等待线程
  for(int i=0;i<5;i++)
  pthread_join(tids[i],nullptr);
  return 0;
}

代码执行结果:

为什么会出现抢到负数票的问题呢?

多个线程都执行这个抢票代码,由于线程之间可能是并行的,在票数为1时,多个线程都判断到tickets>0,于是每个线程都进入了if语句里,进而多抢了票。

线程之间可能是并发的,一个线程执行完判断逻辑为true,还没来得及对tickets--就切换了,下一个线程判断tickets依然大于0,于是就有多个线程进入抢不够的票。

二.单核CUP上线程并发没有并行也会引发线程安全问题

举例说明

i++本质也不是线程安全的(不是原子的):

线程a、b并发执行时,线程a先执行第一步将 i 放入AL中,第二步加法器++,此时线程突然被切走带走自己的硬件上下文(由于未进行第三步,内存中的i还未成功++),b线程开始执行,b线程执行完毕,内存中的i变为1,然后a线程又被调度,将自己的硬件上下文拷回寄存器,AL中的值为1,再接着上次的进度执行第三步,将1拷回内存,内存中的i最终为1。但我们想要的结果一定是2,由于两个线程对共享资源i的访问不是原子的࿰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

无极太族

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

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

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

打赏作者

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

抵扣说明:

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

余额充值