C++ 我需要一个互斥锁来阅读吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1525189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:17:00  来源:igfitidea点击:

Do I need a mutex for reading?

c++multithreadingmutex

提问by

I have a class that has a state (a simple enum) and that is accessed from two threads. For changing state I use a mutex (boost::mutex). Is it safe to check the state (e.g. compare state_ == ESTABLISHED) or do I have to use the mutex in this case too? In other words do I need the mutex when I just want to read a variable which could be concurrently written by another thread?

我有一个具有状态(一个简单的枚举)并且可以从两个线程访问的类。为了改变状态,我使用了互斥锁 (boost::mutex)。检查状态是否安全(例如比较 state_ == ESTABLISHED)或者在这种情况下我是否也必须使用互斥锁?换句话说,当我只想读取一个可以由另一个线程同时写入的变量时,我是否需要互斥锁?

回答by jalf

It depends.

这取决于。

The C++ language says nothing about threads or atomicity.

C++ 语言没有提及线程或原子性。

But on mostmodern CPU's, reading an integer is an atomic operation, which means that you will always read a consistent value, even without a mutex.

但是在大多数现代 CPU 上,读取整数是一种原子操作,这意味着即使没有互斥锁,您也将始终读取一致的值。

However, without a mutex, or some other form of synchronization, the compiler and CPU are free to reorder reads and writes, so anything more complex, anything involving accessing multiple variables, is still unsafe in the general case.

但是,如果没有互斥锁或某种其他形式的同步,编译器和 CPU 可以自由地重新排序读取和写入,因此任何更复杂的事情,任何涉及访问多个变量的事情,在一般情况下仍然是不安全的。

Assuming the writer thread updates some data, and then sets an integer flag to inform other threads that data is available, this could be reordered so the flag is set beforeupdating the data. Unless you use a mutex or another form of memory barrier.

假设写线程更新一些数据,然后设置一个整数标志来通知其他线程数据可用,这可以重新排序,以便更新数据之前设置标志。除非您使用互斥锁或其他形式的内存屏障。

So if you want correct behavior, you don't need a mutex as such, and it's no problem if another thread writes to the variable while you're reading it. It'll be atomic unless you're working on a very unusual CPU. But you doneed a memory barrier of some kind to prevent reordering in the compiler or CPU.

因此,如果您想要正确的行为,则不需要这样的互斥锁,并且在您读取变量时另一个线程写入该变量也没有问题。除非你在一个非常不寻常的 CPU 上工作,否则它将是原子的。但是您确实需要某种内存屏障来防止在编译器或 CPU 中重新排序。

回答by Ernelli

You have two threads, they exchange information, yes you need a mutex and you probably also need a conditional wait.

你有两个线程,它们交换信息,是的,你需要一个互斥锁,你可能还需要一个条件等待。

In your example (compare state_ == ESTABLISHED) indicates that thread #2 is waiting for thread #1 to initiate a connection/state. Without a mutex or conditionals/events, thread #2 has to poll the status continously.

在您的示例中(比较 state_ == ESTABLISHED)表示线程 #2 正在等待线程 #1 启动连接/状态。如果没有互斥或条件/事件,线程 #2 必须连续轮询状态。

Threads is used to increase performance (or improve responsiveness), polling usually results in decreased performance, either by consuming a lot of CPU or by introducing latencey due to the poll interval.

线程用于提高性能(或提高响应能力),轮询通常会导致性能下降,要么消耗大量 CPU,要么由于轮询间隔引入延迟。

回答by geva30

actually, there is no reason to lock access to the object for reading. you only want to lock it while writing to it. this is exactly what a reader-writer lock is. it doesn't lock the object as long as there are no write operations. it improves performance and prevents deadlocks. see the following links for more elaborate explanations :

实际上,没有理由锁定对对象的访问以进行读取。您只想在写入时锁定它。这正是读写锁。只要没有写操作,它就不会锁定对象。它可以提高性能并防止死锁。有关更详细的解释,请参阅以下链接:

wikipediacodeproject

维基百科代码项目

回答by Jeff Ober

Yes. If thread a reads a variable while thread b is writing to it, you can read an undefined value. The read and write operation are not atomic, especially on a multi-processor system.

是的。如果线程 a 在线程 b 写入变量时读取变量,则可以读取未定义的值。读写操作不是原子操作,尤其是在多处理器系统上。

回答by EFraim

Generally speaking you don't, if your variable is declared with "volatile". And ONLY if it is a single variable - otherwise you should be really careful about possible races.

一般来说,如果您的变量是用“volatile”声明的,则不会。并且仅当它是单个变量时 - 否则你应该非常小心可能的种族。

回答by aJ.

The access to the enum ( read or write) should be guarded.

应该保护对枚举(读或写)的访问。

Another thing: If the thread contention is less and the threads belong to same process then Critical section would be better than mutex.

另一件事:如果线程争用较少并且线程属于同一进程,那么临界区将比互斥锁更好。