约翰·米切尔(John C. Mitchell)对“编程语言中的概念”中的这种引用感激不已:
“原子性阻止一个等待过程的单个语句与同一个信号量上的另一个等待的单个语句交错 . ”
等待和信号操作需要是原子的,这通常是由一些“低级”获取锁定的机制强制执行 - 禁用中断,禁用抢占,测试和设置......但是,从概念上讲,这些锁如何以某种方式“私有”对于每个信号量实例?
换句话说,是否允许例如一个线程在开始时获取锁定,然后在一个信号量上执行等待操作的中间被抢占,之后另一个线程在某些其他信号量的等待操作开始时获取锁定并且进入其等待操作的主体,以便两个线程同时在不同信号量的等待操作中?或者,不久, two different semaphores 上的等待操作是否相互排斥?
我的观点是,如果线程在等待操作 on one semaphore s1中获取锁定,是否允许另一个线程在等待操作 on another semaphore s2中同时获取锁定?我强调这是两个不同的信号量实例,而不是同一个 .
例如:
class Semaphore {
...
public:
void wait();
...
}
void Semaphore::wait(){
lock();
//POINT OF CONTINUATION FOR THREAD 2!//
if(--val<0){
//POINT OF PREEMPTION FOR THREAD 1!//
block();
}
unlock();
}
Semaphore s1;
Semaphore s2:
...
所以...
允许在某个执行点允许一个线程在// POINT OF PREEMPTION FOR THREAD 1!//的信号量s1上执行等待操作时被抢占,并且控制转移到另一个线程,该线程在// POINT执行信号量s2的等待操作对于线程2的继续!// ...
...要么...
是否允许来自一个信号量的等待操作指令与来自另一个信号量的等待操作指令交错?
..要么...
是否允许多个线程同时在 different 信号量上进行等待操作?
对不起我的啰嗦,但我真的很难澄清我的问题 . 提前致谢 .
1 回答
是的,这是允许的 . 使用两个不同的锁而不是对所有内容使用相同的锁的原因之一是避免不必要的依赖性 .
绝对 .
绝对 .
禁止任何这些事情会严重损害性能,没有任何好处 . 争用是多线程性能的敌人 .