总结一下线程间同步与互斥生 产者消费者问题
一 互斥锁(mutex)
对于多线程的程序,访问冲突的问题是很普遍的,解决的办法是引⼊入互斥锁(Mutex,MutualExclusive Lock),获得锁的线程可以完成“读-修改-写”的操作,然后释放锁给其它线程,没有获得锁的线程只能等待而不能访问共享数据,这样“读-修改-写”三步操作组成一个原子操作,要么都执行,要么都不执行,不会执行到中间被打断,也不会在其它处理器上并行做这个操作。
互斥锁的两个基本操作lock 和unlock的实现:为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令,该指令的作用是把寄存器和内存单元的数据相交换,由于只有一条指令,保证了原子性,即使是多处理器平台,访问内存的 总线周期也有先后,一个处理器上的交换指令执行时另一个处理器的交换指令只能等待总线周期。
以x86为例的lock和unlock的伪代码
lock:
movb $0, %al
xchgb %al, mutex
if(al寄存器的内容 >0)
{ return 0;
}else
挂起等待;
goto lock;
unlock:
movb $1, mutex
唤醒等待mutex的线程;
retrun 0;
也许还有读者好奇,“挂起等待”和“唤醒等待线程”的操作如何实现?每个Mutex有⼀一个等待队列,一个线程要在Mutex上挂起等待,首先在把自己加入等待队列中,然后置线程状态为睡眠,然后调用调度器函数切换到别的线程。一个线程要唤醒等待队列中的其它线程,只需从等待队列中取出一 项,把它的状态从睡眠改为就绪,加入就绪队列,那么下次调度器函数执行时就有可能切换到被唤醒的线程。
介绍下相关函数:
(1)互斥锁的创建和销毁