Linux多线程之线程互斥

(。・∀・)ノ゙嗨!你好这里是ky233的主页:这里是ky233的主页,欢迎光临~icon-default.png?t=N7T8https://blog.csdn.net/ky233?type=blog

点个关注不迷路⌯'▾'⌯

目录

一、互斥

1.线程间的互斥相关背景概念

2.互斥锁

三、可重入和线程安全

1.概念

2.常见的线程安全和不安全的问题

3.常见的可重入与不可重入情况

4.可重入与线程安全的联系

5.可重入与线程安全的区别

四、死锁

1.死锁的四个必要条件

2.避免死锁的方法


一、互斥

1.线程间的互斥相关背景概念

  • 临界资源:多线程执行流共享的情况下,同一时间只能由一个执行流访问的资源就叫做临界资源
  • 临界区:每个线程内部,访问临界自娱的代码,就叫做临界区
  • 互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用
  • 原子性:不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成

 接下来验证一个问题,如果多线程访问同一个全局变量,并对它进行数据计算,多线程会互相影响吗?

一个看似没问题的多线程抢票程序

void* getTickets(void* args)
{
    (void)args;
    while(1)
    {
        if(tickets>0)
        {
            usleep(1000);
            printf("%p:%d\n",pthread_self(),tickets);
            tickets--;
        }
        else
        {
            break;
        }
    }
    return nullptr;
}

int main()
{
    pthread_t t1,t2,t3;
    pthread_create(&t1,nullptr,getTickets,nullptr);
    pthread_create(&t2,nullptr,getTickets,nullptr);
    pthread_create(&t3,nullptr,getTickets,nullptr);
    pthread_join(t1,nullptr);
    pthread_join(t2,nullptr);
    pthread_join(t3,nullptr);
}

抢票到最后,不仅仅出现了有两个11张票的情况,甚至还出现了剩余-1张票的情况!所以如果我们不加以保护的话就会引起这种现象

我们用的方式是--,我们都知道--分为三个动作,先在对应的线程把数据读取到CPU中,然后--,最后返回内存,可是如果在还没--的时候cpu进行调度切换了呢?就会导致这个线程认为还有999张票,下一个也是认为999张票,可是下一个线程做完操作了把998返回去了,然后这时候刚刚的线程进来了,那么这个时候就会把之前保存在线程上下文数据中的999返回到CPU中,然后继续没做完的操作并返回998,那么这个时候已经卖出去两张票了,可是剩余的却是998张票!

这样就导致了我们在并发访问的时候,导致了我们数据不一致的问题!

那么要怎么避免这样的问题产生呢!

2.互斥锁

1.用法

pthread_mutex_t mtx;//首先要先定义一把锁
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
//之后对锁进行初始化操作
  • 参数一:开始定义的锁
  • 参数二:初始化时互斥锁的相关属性设置,传递nullptr使用默认的属性
  • 返回值:成功为0,失败返回错误码
  • 如果是全局或者静态的也可以使用这个宏来初始化:PTHREAD_MUTEX_INITIAILZER
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值