互斥是否保证收购的顺序?

Jas*_*n R 25 multithreading c++11

一位同事最近遇到了一个问题,归结为我们认为具有两个线程的C++应用程序中的以下事件序列:

  • 线程A持有互斥锁.

  • 当线程A持有互斥锁时,线程B会尝试锁定它.由于它被保持,线程B被暂停.

  • 线程A完成它持有互斥锁的工作,从而释放互斥锁.

  • 此后不久,线程A需要触摸受互斥锁保护的资源,因此它会再次锁定它.

  • 似乎线程A再次被赋予互斥锁; 线程B仍在等待,即使它首先"询问"锁定.

这个事件序列是否适合C++ 11 std::mutex和/或pthreads 的语义?老实说我以前从未想过互斥体的这个方面.

Ser*_*eyA 24

已知问题.C++互斥体是操作系统提供的互斥体之上的薄层,而OS提供的互斥体通常不公平.他们不关心FIFO.

同一枚硬币的另一面是线程通常不会被抢占,直到它们的时间片耗尽.因此,此方案中的线程A可能会继续执行,并因此而立即获得互斥锁.

  • 另一个看待它的是,当A首先放弃互斥锁时,操作系统只是将B标记为准备好运行.操作系统实际上不会执行上下文切换,直到它绝对必须,因为它很昂贵.当A的时间片到期时,或者A调用阻塞函数,或者B的优先级高于A(当A放弃互斥体时由OS评估),它会发生(如你所说).如果您开始使用线程优先级以正确的顺序发生事情,那么您可能需要一个可以解决优先级反转的操作系统(因此不能存储Linux或Windows.Linux + PREMPT_RT就可以了). (5认同)
  • Windows 本机同步类型(CreateMutex、CreateSemaphore、WaitForSingleObject、WaitForMultipleObjects)使用某种类型的队列,以便根据实际测试按 FIFO 顺序授予请求,但我还没有找到相关文档。 (2认同)