【Linux 多线程互斥】如何保证锁的原子性(互斥的原理)

  1. 临界资源:可以被多个执行流(线程或者叫轻量级进程)同是访问的(多个执行流共享的,比如:全局、堆等等);
  2. 临界区:访问这些临界资源的代码;
  3. 原子性:没有中间态,不做或者做完;

1.展示没有互斥的程序 

1.1.一个购票系统,有5个线程在购票

#include<iostream>
#include<cstdio>
#include<unistd.h>
#include<pthread.h>

int tickets=100;
void* thread_run(void* args)
{
    int tmp=*((int*)args);
    while(1)
    {
        if(tickets>0)//购表
        {
            usleep(10000);
            tickets--;
            printf("我是%d线程,还剩%d\n",tmp,tickets);
        }
        else
        {
            printf("没票了\n");
            break;
        }
    }
    return (void*)0;
}
int main()
{
    pthread_t tid[5];
    for(int i=0;i<5;i++)//创建5个线程
    {
        int* t=new int(i);
        pthread_create(tid+i,NULL,thread_run,(void*)t);
    }
    for(int i=0;i<5;i++)
    {
        pthread_join(tid[i],NULL);
    }
    return 0;
}

执行结果:不是每次都会产生这样的结果 ,把票购成负数了不合理

 原理:

 2.互斥

互斥整个过程:保持临界资源的原子性

pthread_mutex_t lock;//锁

pthread_mutex_init(&lock,NULL);//初始化

pthread_mutex_lock(&lock);//加锁

//临界区

pthread_mutex_unlock(&lock);//解锁

pthread_mutex_destroy(&lock);//删除锁

 修改上面代码

#include<iostream>
#include<cstdio>
#include<unistd.h>
#include<pthread.h>

pthread_mutex_t lk;//锁
int tickets=100;
void* thread_run(void* args)
{
    int tmp=*((int*)args);
    while(1)
    {
        pthread_mutex_lock(&lk);//加锁
        if(tickets>0)
        {
            usleep(10000);
            tickets--;
            printf("我是%d线程,还剩%d\n",tmp,tickets);
        }
        else
        {
            printf("没票了\n");
            pthread_mutex_unlock(&lk);//解锁
            break;
        }
        pthread_mutex_unlock(&lk);//解锁
    }
    return (void*)0;
}
int main()
{
    pthread_mutex_init(&lk,NULL);//初始化
    pthread_t tid[5];
    for(int i=0;i<5;i++)
    {
        int* t=new int(i);
        pthread_create(tid+i,NULL,thread_run,(void*)t);
    }
    for(int i=0;i<5;i++)
    {
        pthread_join(tid[i],NULL);
    }
    pthread_mutex_destroy(&lk);//删除锁
    return 0;
}

3.如何保证锁的原子性(互斥的原理)

为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令(汇编):作用是把寄存器和内存单元的数据相交换

过程:每一个线程调用lock,会先把自己上下文中关于锁的变量设为0,然后和使用一行代码(原子性)交换上下文的数据和锁的数据,锁的数据被换走变成0,其它线程来交换还是0,会挂起等待循环这个过程,直到换走数据的线程解锁为止;

 如果交换走锁数据的线程时间片到了,被调度那么它也是抱着锁走的,其他线程还是不能执行临界资源

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值