多线程系列——Mutex的两个基本操作lock和unlock的实现

来源:互联网 发布:mac系统顿号怎么打 编辑:程序博客网 时间:2024/06/07 09:05
假设Mutex变量的值为1表示互斥锁空闲,这时某个进程调用lock可以获得锁,
而Mutex的值为0表示互斥锁已经被某个线程获得,其它线程再调用lock只能挂起等待
大多数结构都提供swap或exchange指令,该指令的作用是把寄存器和内存单元数据交换
由于只有一条指令,确保原子性,即使多处理器平台,访问内存的总线周期亦有先后,一个处理器执行交换指令时,另一处理器只能等待总线周期。
lock
movb $0 ,%al
xchgb %al,mutex
if(al寄存器内容>0)
{
return 0;
}
else
{
挂起等待;
}
goto lock;
unclock
movb $1,mutex
唤醒等待mutex的线程
return 0 ;
每个Mutex都有一个等待队列,一个线程在mutex上挂起等待,
首先 把自己加入等待队列中,然后致线程状态为睡眠,
然后调用 调度函数切换到别的线程。
一个线程要唤醒别的线程,需从等待队列取出一项,把它状态从睡眠改为就绪,放入就绪队列。
下次调度函数就有可能切换到该线程。
死锁(Deadlock)
  • 同一线程先后两次调用lock,在第二次调用时,由于锁已被自己占用,该线程会挂起而等待别的线程释放锁,此时该线程因挂起而没有机会释放锁,因此永远挂起等待。
  • 线程A获得锁1,线程B获得了锁2,此时线程A调用lock试图获得锁2,因此挂起等待线程B释放锁2,
线程B也调度lock试图获得锁1而需要挂起等待线程A释放锁1,结果线程A和线程B永远挂起。
原则:
  • 如果所有线程在需要多个锁时都按相同的先后顺序(常见的是按Mutex变量的地址顺序)获得锁,则不会出现死锁。
  • 使用pthread_mutex_trylock调用代替pthread_mutex_lock调用,以免死锁

谢谢大家参考和指正,由于是自学的东西总结的,所以也许有不对的地方,望见谅。


原创粉丝点击