简体   繁体   English

我是否应该在一个线程中锁定一个变量,如果我只需要在其他线程中使用它的值,为什么它不工作呢?

[英]Should I lock a variable in one thread if I only need it's value in other threads, and why does it work if I don't?

I am aware of this question , but I believe my concerns are very different. 我知道这个问题 ,但我相信我的担忧是非常不同的。

I recently created an SDL application, using threading and OpenGL. 我最近使用线程和OpenGL创建了一个SDL应用程序。 I have one thread running in a loop, which continually updates the state of the objects I draw to the screen. 我有一个线程在循环中运行,它不断更新我绘制到屏幕的对象的状态。 The states are very simple, it is just a boolean array (when the array value is true, I draw it, when it is false, I don't). 状态非常简单,它只是一个布尔数组(当数组值为true时,我绘制它,当它为假时,我没有)。

Currently, I have no mutex lock on any of my variables and everything is working just fine. 目前,我的任何变量都没有互斥锁,一切正常。 Even if only half of the state array was updated between a draw, the framerate is much higher (or at least equal to) the update rate, so it would be acceptable to have a half-updated state. 即使只有一半的状态数组在绘制之间更新,帧速率也要高得多(或至少等于)更新速率,因此具有半更新状态是可以接受的。

Now, I initially started working on a similar idea to this on an embedded system using interrupts. 现在,我最初在使用中断的嵌入式系统上开始研究类似的想法。 Every once in a while, an interrupt would trigger, update the state array, and the execution would continue. 每隔一段时间,一个中断就会触发,更新状态数组,执行将继续。 Now that I'm on a multi-core desktop, and updating the array simultaneously, I'm wondering why nothing bad is happening, since I am technically reading and writing to the same memory location at the same time . 现在,我是一个多核桌面上,并同时更新数组,我不知道为什么没有什么不好的正在发生的事情,因为我在技术上阅读并同时写入同一个存储单元。

  • Is it just by chance, or is there a reason there's no memory access violations happening? 这只是偶然的,还是有理由没有发生内存访问违规?
  • If it is acceptable for the state of the variable to change just before, during, or just after the value is used, should I bother using a mutex lock? 如果在使用该值之前,期间或之后变量的状态是可以接受的,那么我是否应该使用互斥锁?

Thank you for your help. 谢谢您的帮助。


Edit: Additional information - the array is created dynamically, but when it is created/deleted, I do use a mutex (I figured accessing deleted memory wouldn't be looked kindly upon :P). 编辑:附加信息 - 数组是动态创建的,但是当它被创建/删除时,我确实使用了互斥锁(我认为访问已删除的内存不会看起来很友善:P)。

In theory, it's completely invalid (undefined behavior) to access memory like this without some synchronization. 理论上,在没有某些同步的情况下访问这样的内存是完全无效的(未定义的行为)。

In practice, it's moderately safe as long as: 在实践中,只要符合以下条件,它就是中等安全的:

  1. Only one thread is writing and the others are all reading. 只有一个线程在写,其他线程都在读。
  2. You don't care if the readers don't see some of the changes made until sometime later (possibly much later than the actual time they're written. 如果读者在一段时间之后没有看到一些变化(可能比他们写入的实际时间得多),你不在乎。
  3. You don't care if the readers see out-of-order changes, ie they see some changes that were made later without seeing other changes that were made earlier. 您不关心读者是否看到无序更改,即他们会看到稍后进行的某些更改,而不会看到之前进行的其他更改。

Issues 2 and 3 are a non-issue on x86, but can occur on nearly every other real-world multi-core/SMP machine. 问题2和3在x86上不是问题,但几乎可以在所有其他真实世界的多核/ SMP机器上发生。 You could mitigate them with some machine-specific asm (or compiler intrinsics) to insert memory barriers at appropriate points. 您可以使用某些特定于机器的asm(或编译器内在函数)来缓解它们,以在适当的位置插入内存屏障

The boolean array elements are can be set/read with an atomic operation, there is not need for a mutex. 布尔数组元素可以通过原子操作设置/读取,不需要互斥锁。 You need a mutex to protect a structure to make sure that it stays consistent. 您需要一个互斥锁来保护结构,以确保它保持一致。 Since your booleans are independent there is no problem. 由于你的布尔是独立的,所以没有问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 (Qt5,线程)我遵循的示例不起作用 - (Qt5, Threads) The examples I'm following don't work 我不明白为什么我需要按特定顺序放置两行才能使其工作(递归) - I don't understand why I need to put two lines in a specific order for it to work (recursion) 我应该更喜欢std :: thread还是Boost线程? - Should I prefer std::thread or Boost threads? 如果我确定每个线程总是将相同的值写入共享 memory,我应该使用锁吗? - should I use a lock if I am sure that every thread will always write the same value to shared memory? 我无法正确执行这些变量声明…为什么这些参数不起作用? 我只是将n值设置为数组长度 - I can't get those variable declarations right…Why those parameters don't work? I just set the n value as arrays length 我是否需要保护对仅在同一线程中修改的变量的读取? - Do I need to protect the read on a variable that is only modified in the same thread? 我应该总是在多线程编程中锁定全局数据吗,为什么或为什么不呢? - should i always lock the global data in multi-thread programming, why or why not? 为什么我不需要在地图的.at()方法中使用解引用运算符? - Why don't I need to use the dereference operator with a map's .at() method? 我是否需要保护一个线程写入并被多个线程读取的变量? - Do I need to guard a variable that is written by one thread and read by many? Qt:如果只有一个编写器线程,是否需要互斥体? - Qt: do I need a mutex if there is only one writer thread?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM