C ++线程,共享数据 [英] C++ Thread, shared data

查看:60
本文介绍了C ++线程,共享数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,其中有2个线程正在运行...有什么证明,当我从一个线程更改一个全局变量,另一个会注意到这个变化?
我没有任何同步或互斥系统到位...但应该这个代码工作的所有时间(想象一个全局 bool 命名 dataUpdated ) :



主题1:

  while(1){
if(dataUpdated)
updateScreen();
doSomethingElse();
}

主题2:

  while(1){
if(doSomething())
dataUpdated = TRUE;
}

一个编译器喜欢gcc优化这个代码,检查全局值,只考虑它在编译时的值(因为它在同一个thred中变化了)?



PS:这是一个类似游戏的应用程序,它真的没有什么重要的,如果有价值被写入时会有一个读...所有重要的是变化被其他线程注意到。

解决方案

是的。



首先,正如其他人提到的,你需要使dataUpdated volatile;否则编译器可以自由地将它读出循环(取决于它是否可以看到doSomethingElse没有触及它)。



其次,依赖在您的处理器和订购需求,您可能需要内存屏障。易失性足以保证另一个处理器将最终看到改变,但不足以保证改变将按照它们被执行的顺序被看到。你的例子只有一个标志,所以它不会真正显示这种现象。如果你需要和使用内存屏障,你应该不再需要volatile



Volatile被视为有害 Linux内核内存障碍良好的背景下的潜在问题;我真的不知道类似的任何类似的专门为线程。幸运的是,线程不会像硬件外设那样频繁地引发这些问题,尽管你描述的情况(一个标志指示完成,如果标志被设置,其他数据假定是有效的)正是这样的事情,其中​​顺序matterns ...


I have an application where 2 threads are running... Is there any certanty that when I change a global variable from one thread, the other will notice this change? I don't have any syncronization or Mutual exclusion system in place... but should this code work all the time (imagine a global bool named dataUpdated):

Thread 1:

while(1) {
    if (dataUpdated)
    	updateScreen();
    doSomethingElse();
}

Thread 2:

while(1) {
    if (doSomething())
    	dataUpdated = TRUE;
}

Does a compiler like gcc optimize this code in a way that it doesn't check for the global value, only considering it value at compile time (because it nevers get changed at the same thred)?

PS: Being this for a game-like application, it really doen't matter if there will be a read while the value is being written... all that matters is that the change gets noticed by the other thread.

解决方案

Yes. No. Maybe.

First, as others have mentioned you need to make dataUpdated volatile; otherwise the compiler may be free to lift reading it out of the loop (depending on whether or not it can see that doSomethingElse doesn't touch it).

Secondly, depending on your processor and ordering needs, you may need memory barriers. volatile is enough to guarentee that the other processor will see the change eventually, but not enough to guarentee that the changes will be seen in the order they were performed. Your example only has one flag, so it doesn't really show this phenomena. If you need and use memory barriers, you should no longer need volatile

Volatile considered harmful and Linux Kernel Memory Barriers are good background on the underlying issues; I don't really know of anything similar written specifically for threading. Thankfully threads don't raise these concerns nearly as often as hardware peripherals do, though the sort of case you describe (a flag indicating completion, with other data presumed to be valid if the flag is set) is exactly the sort of thing where ordering matterns...

这篇关于C ++线程,共享数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆