为什么sizeof(std :: mutex)== 40(gcc,clang,icc)?

Wal*_*ter 6 c++ mutex c++11

而不是sizeof(std::atomic<bool>)==1?

一个互斥体可以通过一个简单的实现std::atomic<bool>,所以我认为互斥体的大小可以小到那个,或者可能是4(32位).

Max*_*kin 12

有一个bool你只能实现自旋锁.请注意,这将是一个不公平的锁,因为没有什么可以确保服务员排队,所以在极端情况下有可能在高争用情况下线程可以被永久阻止,因为它总是会失去获得锁的竞争.

互斥实现需要操作系统的支持才能使等待的线程进入休眠状态.因此,互斥锁需要一个标志,告诉它是否被锁定以及某种形式的队列描述符,它允许等待线程进入休眠状态并唤醒它们.如果您希望互斥锁能够支持递归锁定,健壮性,可选旋转,优先级反转保护等,则需要更多成员.

  • @MaximYegorushkin:的确如此; 你只能使用`int`来实现一个Posix互斥锁.但问题不在于Posix互斥体,它与`std :: mutex`有关(就像许多C++库一样)不需要强制执行前置条件. (3认同)
  • @MaximYegorushkin - 是的,这使得它“不是互斥锁”。 (2认同)
  • @MartinJames:它使它成为一个具有前提条件的互斥体.这并不能使它"不是一个互斥体",它只是使调试变得不那么容易执行前提条件.`std :: mutex`本身具有相同的前提条件,如果你打破它,则使用UB.使用RAII锁定类型在外部强制执行非常容易. (2认同)

Mik*_*our 11

GNU库通常使用Posix线程来实现标准线程库.它使用单一类型pthread_mutex_t来表示几种不同类型的互斥体; 因此它包含更复杂的互斥锁所需的各种字段(例如递归互斥锁的计数器),以及指定类型的字段.

原则上,在操作系统的适当支持下,您std::mutex可以使用少至一个字节的用户内存.(在Linux上,它必须是一个int;在其他平台上,它可能是内核资源的整数或指针大小的句柄).据推测,使用经过充分测试的现有实现的好处被认为超过了每个互斥锁节省几十个字节的好处.


das*_*ght 6

可以通过简单的方式实现互斥锁 std::atomic<bool>

考虑到这mutex::lock是必需的操作,它看起来不太可能,并且std::atomic<bool>很可能是非锁定类型.你可以while在compare_exchange_strong调用周围放一个循环,但这不一样mutex::lock,因为它在整个等待期间浪费了CPU.

通常,std::mutex比bool定义多线程行为的简单要复杂得多,解释它的相当大的大小,这取决于编译器:例如,在ideone上sizeof(mutex)是24.