两个独立线程在不同信号量上执行的两个等待操作是否可以在执行过程中交错?

Can two wait operations executed by two separate threads on different semaphores be interleaved during execution?

约翰·C·米切尔 (John C. Mitchell) "Concepts in Programming Languages" 的这段引文让我深受鼓舞:

"Atomicity prevents individual statements of one wait procedure from being interleaved with individual statements of another wait on the same semaphore."

等待和信号操作需要是原子的,这通常由一些 "lower" 级别的获取锁的机制强制执行 - 禁用中断,禁用抢占,测试和设置......但是,从概念上讲,这些锁如何可以每个信号量实例以某种方式"private"?

换句话说,是否允许例如一个线程在对一个信号量执行等待操作的过程中开始获取锁,然后在执行等待操作的过程中被抢占,然后另一个线程在等待操作开始时获取锁在其他一些信号量上并进入其等待操作的主体,以便两个线程同时在不同信号量上进行等待操作?或者,简而言之,两个不同信号量上的等待操作是否互斥?

我的观点是,如果线程在等待操作上获取锁在一个信号量 s1 上,是否允许另一个线程在等待操作中同时获取锁在另一个信号量上 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 执行等待操作时被抢占,并将控制转移到另一个执行信号量等待操作的线程s2 位于 //线程 2 的延续点!//...

...或...

是否允许一个信号量的等待操作指令与另一个信号量的等待操作指令交错?

..或...

是否允许多个线程同时在不同个信号量上等待操作?

抱歉我的啰嗦,但我真的很难澄清我的问题。提前致谢。

是的,这是允许的。你会使用两个不同的锁,而不是对所有东西都使用同一个锁,原因之一是为了避免像这样不必要的依赖。

Is it allowed for instructions of wait operation from one semaphore to be interleaved with instruction of wait operation from another semaphore?

绝对。

Is it allowed for more than one threads to be in wait operations on different semaphores at the same time?

绝对。

禁止任何这些事情都会严重损害性能而没有任何好处。争用是多线程性能的大敌。