【问题标题】:Can two wait operations executed by two separate threads on different semaphores be interleaved during execution?由两个单独线程在不同信号量上执行的两个等待操作可以在执行期间交错吗?
【发布时间】:2016-12-20 01:34:44
【问题描述】:

John C. Mitchell 的“编程语言概念”中的这段引文激励了我:

"原子性防止一个等待过程的单个语句被 与另一个在同一信号量上等待的单独语句交错。"

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

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

我的观点是,如果线程在等待操作在一个信号量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 的继续点!//...

...或...

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

..或...

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

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

【问题讨论】:

  • 我无法理解您的要求。信号和信号量只是并发工具箱中的不同工具。 (还有其他。)不同的工具更适合不同的事情。
  • 彼得森算法更像是一种学术练习。当您尝试实施它时,它做出的假设可能不一定得到保证。最好依靠为强制互斥而设计的硬件指令。
  • 对不起,我的困惑。我试图澄清我的观点,所以我编辑了问题。我的问题更多的是关于信号量的实现,等待/信号操作的定义是否要求它们必须在物理上不可分割?
  • 不要忘记,如果收到另一个信号,信号处理程序本身可能会被中断。
  • 好的,但是如果我们禁用所有可屏蔽的中断,那么我们会阻止任何异步抢占,这是我的问题的重点(例如由计时器启动),并且控制转移只能通过进程的意志来执行当前使用的处理器(例如通过执行软件中断指令)。

标签: multithreading operating-system synchronization semaphore


【解决方案1】:

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

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

绝对的。

是否允许多个线程同时对不同的信号量进行等待操作?

绝对的。

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

【讨论】:

  • 非常感谢您的回答。但是,我们如何在不禁用中断或抢占的情况下在单处理器系统上为每个信号量实现不同的锁呢?那么我们是否应该使用一些忙等待的算法呢?
  • 我不听你的问题。如果您选择使用不同的锁,则意味着您不想要任何特别的东西,所以没有什么特别的事情可做——我们不在乎是否有抢占。如果您使用相同的锁,那么锁可以保护事物,这就是它的工作。
  • 我的意思是如果获取锁需要是原子的,我们如何执行它?或者,更具体地说,我应该如何实现 lock();和解锁();我的问题示例中的操作,以提供更多独立线程可以同时在不同信号量上等待操作的效果?
  • 这取决于硬件。通常,它是通过在 CPU 防止中断的原子指令期间将包含锁定/解锁标志的缓存行固定到缓存中来完成的。在没有硬件帮助的情况下,您可能必须禁用中断。
  • “如果没有硬件帮助,您可能必须禁用中断”。如果我理解得很好,对于 lock() 和 unlock() 的实现,我不能使用一些不需要特殊硬件指令并依赖于常规读取原子性的忙等待算法的进入和退出协议(例如 Decker 算法) /写指令?
猜你喜欢
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-21
相关资源
最近更新 更多