Why is std::mutex neither copyable nor movable? [duplicate]

帅比萌擦擦* 提交于 2020-12-26 05:18:06

问题


Could somebody tell the reasons why std::mutex is neither copyable nor movable? Somebody told me that it has some relationship to avoid resource waste. Why the copy constructor of std::mutex should be marked as deleted? If not, is there any potential problem? Its copy constructor is clearly marked as deleted, but I have not seen such declaration for its movement constructor. So why does cppreference say std::mutex is not movable?


回答1:


Expanding a bit on the other answers, basic locks such as Mutexes are the most basic objects in the language design providing atomic operations, lock and unlock here. These might own an OS implemented handle (native_handle) that is a handle for a hardware implemented object, and might even skip the intermediate handle.

Copying such a handle of course, is non-trivial (you can't copy a piece of hardware, and sometimes even a OS handle, trivially). Moving it is potentially worse - move leaves the object in an unspecified state, but by its nature, a mutex is shared across threads. If you gut it on one thread, you would somehow have to inform all other threads - more likely you would just have breaking code. This is a lot of overhead for no potential benefit (I can see).

As to why the move constructor is not explicitly deleted in your reference - no default move constructor is created if there is a (non-default) defined destructor (12.8, comment 9), so there is no need to delete it.




回答2:


In addition to the answer below, mutex handles cannot be copied at the OS level either. In Windows, you have to create a named mutex and then open a new handle based on that name, for example, intended to be used in a new thread/process and std::mutex never creates named objects. So even if there was a copy constructor, it would be impossible to implement it.

Generally, synchronization objects' semantics are different than some plain other object's, even if they are apparently wrapped in a C++ class




回答3:


std::mutex has no copy constructor. If you send a copy, each will lock it's own copy and you don't prevent race-condition. Helping programmers not shoot themselves in the foot.

30.4.1 Mutex requirements

A mutex object facilitates protection against data races and allows safe synchronization of data between execution agents (30.2.5). An execution agent owns a mutex from the time it successfully calls one of the lock functions until it calls unlock.

30.2.5 Requirements for Lockable types [thread.req.lockable]

An execution agent is an entity such as a thread that may perform work in parallel with other execution agents

If you could move, then ownership requirement is broken. And apparently it's already been asked before why std::mutex doesn't have a move constructor?

To add and quote draft on @Kabanus answer to why move is not marked deleted

12.8 Copying and moving class objects [class.copy]

20 If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly declared as defaulted if and only if

  • []
  • []
  • []
  • X does not have a user-declared destructor
  • []


来源:https://stackoverflow.com/questions/62369119/why-is-stdmutex-neither-copyable-nor-movable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!