在多线程对同一块临界资源进行操作时,需要在线程运行时上锁,保证本次线程操作临界资源时,仅有次一个线程进行操作,避免操作混乱错误更改临界资源。例如当多线程同时对一个变量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
}
大概是这个意思,可以用于比较参数在运行时是否被更改,如果没被更改就执行操作,否则想干嘛干嘛的。实现代码我也不是自己写的就不放了,需要的嵌入汇编指令可以。
本文介绍了在多线程编程中如何保证临界资源的安全访问,主要讨论了互斥锁和自旋锁两种同步机制以及原子操作的概念。互斥锁在资源被占用时会使线程进入等待状态,而自旋锁则会让线程持续检查锁的状态。此外,还提到了CAS(Compare and Swap)操作作为无锁编程的一种手段,确保对变量的更新操作的原子性。


被折叠的 条评论
为什么被折叠?



