Linux 并发操作临界资源上锁

本文介绍了在多线程编程中如何保证临界资源的安全访问,主要讨论了互斥锁和自旋锁两种同步机制以及原子操作的概念。互斥锁在资源被占用时会使线程进入等待状态,而自旋锁则会让线程持续检查锁的状态。此外,还提到了CAS(Compare and Swap)操作作为无锁编程的一种手段,确保对变量的更新操作的原子性。


        在多线程对同一块临界资源进行操作时,需要在线程运行时上锁,保证本次线程操作临界资源时,仅有次一个线程进行操作,避免操作混乱错误更改临界资源。例如当多线程同时对一个变量i 执行 i++ 时,无法保证全都是如图的正常情况:线程2在线程1 执行后再次执行

线程 1           线程2  
mov[i] ,eax;
inc     eax;
mov eax,[i];

                 mov[i] ,eax;
                 inc     eax;
                 mov eax,[i];

    会出现对于临界资源操作的混乱行为,对于临界资源的操作会失去顺序,使其不能按需求增减。

线程 1           线程2  
mov[i] ,eax;
inc     eax;
                 mov[i] ,eax;
                 inc     eax;
                 mov eax,[i];
mov eax,[i];

    需要对于临界资源操作进行上锁,常用的锁有互斥锁,自旋锁,院子操作等。在线程的回调函数对临界资源进行访问操作时,对线程上锁保证单一线程操作。

互斥锁


初始化 

pthread_mutex_t mutex;//定义一个互斥锁
pthread_mutex_init(&mutex,NULL);//null 为默认线程 属性

上锁与解锁

pthread_mutex_lock(&mutex);
i++;
pthread_mutex_unlock(&mutex);

自旋锁


初始化

pthread_spinlock_t spinlock;
pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);//初始化参数意为线程分享

上锁与解锁

pthread_spin_lock(&spinlock);
i++;
pthread_spin_unlock(&spinlock);

互斥锁与自旋锁区别


    运行机制区别在于,互斥锁在其他线程调用了正在工作线程的资源时,被锁挡住后会切换线程等待下一次调用。而自旋锁会一直等待下去类似于 while(1),一直等到当前锁释放。

    使用场景区别在于,互斥锁适用于线程内容多,切换线程代价相对较小的情况下,而自旋锁适用于切换代价大于等待代价的情况下。

原子操作


将线程需要的操作转化为一条CPU指令,汇编语言lock为一条,一次性执行完毕。

__asm__ volatile( " lock; 不拉不拉不拉 //命令lock为锁定CPU 必须有
       //你需要的嵌入汇编命令
)

此处必须提到CAS,这个东西,老师suo记住有用喔~~ compare and swap

CAS(a,b,c){
if a==b
   a=c
}

        大概是这个意思,可以用于比较参数在运行时是否被更改,如果没被更改就执行操作,否则想干嘛干嘛的。实现代码我也不是自己写的就不放了,需要的嵌入汇编指令可以。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值