C++多线程问题 - 互斥是唯一的方法吗?
我有一个计数器变量,它将被多个线程访问,这将增加/减少它。它不应该由多个线程同时更新。
我知道您可以创建一个互斥对象,必须在更改相关变量之前获取该对象。在这种情况下,临界区是不合适的,因为有多个函数可以更改相关变量。
还有另一个我可以在不使用互斥体的情况下做到这一点吗?使用互斥体确实会降低性能(请参阅 http://www.codeguru。 com/forum/showthread.php?t=333192)。我相信在Java中,你可以在变量声明中使用一个关键字来实现这一点(它被称为“同步”吗?),但是在C++中有这样的东西吗?
我知道 volatile 不是我要寻找的关键字。
非常感谢。
I have a counter variable which will be accessed by multiple threads which will increment/decrement it. It should not be updated by multiple threads at the same time.
I know that you can create a mutex object which has to be obtained before the variable in question can be changed. A critical section in this case is not appropriate because there are more than 1 function which can change the variable in question.
Is there another I can do this without using the mutex? Using a mutex does have a performance penalty (see http://www.codeguru.com/forum/showthread.php?t=333192). I believe that in Java, there is a key word you can use in the variable declaration to accomplish that (is it called "synchronized"?), but is there such a thing in C++ at all?
I know that volatile is not the keyword I am looking for.
Thank you very much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
大多数处理器都有“原子”递增和递减指令 - 在很大程度上,它们是互斥体的方式是在机器级别实现的。
您可以在自己的代码中访问这些原子指令。 Windows 提供了
InterlockedIncrement()
函数,并且 glib 提供等效函数。在x86汇编语言中,可以直接使用LOCK CMPXCHG
和kin。C++ 对这些概念一无所知——你必须自己使用它们; C++ 中没有用于线程安全的神奇关键字。
请参阅原子指令
Most processors have 'atomic' increment and decrement instructions - in a large part, they are how mutexes are implemented at a machine level.
You can access these atomic instructions in your own code. Windows provides the
InterlockedIncrement()
function, and glib provides equivalents. In x86 assembly language, you can useLOCK CMPXCHG
and kin directly.C++ does not know anything about these concepts - you must use them yourself; there are no magic keywords for thread safety in C++.
See Atomic Instruction
虽然使用原子操作可能是最有效的,但事实上,在多个函数中使用原子操作并不妨碍在此代码或任何其他代码中使用关键部分 - 只需编写一个函数:
并从其他函数中调用它。
While the use of atomic operations is probably the most efficient, the fact that this is used in more than one function is no bar to using a critical section in this or any other code - simply write a function:
and cal it from your other functions.
从描述来看,听起来也许您只需要 InterlockedIncrement 和相关的减量函数。
编辑-这些是Windows功能......我没有停下来问哪个平台。
From the description, it sounds like maybe you only need InterlockedIncrement and the associated decrement function.
Edit - These are Windows functions ... I didn't stop to ask which platform.
这是使用关键部分的常见场景,您需要确保访问变量的每段代码在进入相同的关键部分(或互斥体,或使用任何保护)时都这样做。
This is a common scenario where critical sections are used, you need to assure every piece of code that access the variables do so while entering the same critical section(or mutex, or whichever guarding is used).
在 Win32 IntelockedIncrement/IntelockedIncrement64 和相关操作编译为 x86 指令,允许对 32 或 64 位字(取决于您的体系结构)进行处理器级原子操作。这在简单计数器的情况下工作得很好,但如果您尝试将较大的结构与多个单词同步,这自然不会工作。
PS来自此处,您需要实现的相应asm这是在 x86 上运行的非 Win32 系统上的。
In Win32 IntelockedIncrement/IntelockedIncrement64 and associated operations compile to x86 instructions that allow processor level atomic operations on 32 or 64 bit words (depending on your architecture). This works fine in the case of a simple counter, but naturally won't work if your trying to synchronize a larger structure with multiple words.
PS from here, the corresponding asm you would need to implement this on a non Win32 system running on an x86.
您可以使用原子类型作为计数器变量 - 例如 sig_atomic_t (在 GNU libc 中)。那么就不需要同步,因为竞争条件不会发生,所以对该变量的操作保证是原子的。
You could use atomic type for the counter variable - like sig_atomic_t (in GNU libc). Then there is no need for synchronization, since a race condition cannot happen, the operation on this variable is guaranteed to be atomic.
正如其他人提到的,当前的 C++ 标准中没有任何内容支持原子变量访问。但是,如果您要求 C++ 库支持(我不太清楚),则正在尝试模仿即将推出的 C++ 标准的原子支持 此处。
As others have mentioned, there's nothing in the current C++ standard that supports atomic variable access. If you're asking for C++ library support however (not entirely clear to me), there's an attempt-in-progress to mimic the upcoming C++ standard's atomic support here.
如果您不使用临界区创建单个函数来修改变量,您如何知道您已找到该变量可能被访问的所有位置?
此外,您需要将变量声明为 易失性,只是确保您的编译器不会无意中优化对该变量的任何访问。
How will you know you have found all places the variable might be access if you don't create a single function using a critical section to modify it?
Additionally you will need to declare the variable volatile just make sure your compiler doesn't optimize any accesses to the variable inadvertently.