1

我有一个 C++ 类的小问题......
我有一个私人成员bool clientConnected
和一个吸气剂bool isClientConnected() {return clientConnected;}

现在的问题是.. clientConnected 是从不同的线程设置的。

在主要我有一个循环

while (!x.isClientConnected())
{}

现在如果我在调试配置中编译它。
一切正常......只要将clientConnected设置为true就退出。
但如果我在发布配置中编译它。
编译器将循环优化为它的常量。
并进行以下操作:

00141C01  cmp         al,bl  
00141C03  je          SDL_main+0A1h (141C01h)  

al 的值永远不会再更新。
所以它总是认为它是错误的。
我也尝试了易变的,相同的结果

如何在类中防止这种优化,以便在每次调用时更新值,而不必编写类似的东西

bool z = x.isClientConnected();
while (!z) { z = x.isClientConnected(); }
4

3 回答 3

4

对于踩踏问题,您需要使用线程同步,以保证从一个线程到另一个线程的更改传播。

C++11 对线程有一些直接支持,但我没有使用过。

如果您没有支持该功能的编译器,请尝试使用 Boost 线程。

于 2012-10-13T14:08:46.740 回答
3

volatile http://msdn.microsoft.com/en-us/library/12a04hfd(v=vs.80).aspx看起来像是对您问题的简单回答:

“声明为 volatile 的对象不会在某些优化中使用,因为它们的值可以随时更改。”

volatile bool clientConnected;
bool isClientConnected() const volatile {return clientConnected;}

但是 - 你有循环占用 CPU:

while (!x.isClientConnected())
{}

更好的是等待信号量:

x.waitForConnected();
void X::waitForConnected()
{
   WaitForSingleObject(m_connectedSemaphore, ,....);
}

如何在 MS Windows 中创建/使用信号量请参阅:http: //msdn.microsoft.com/en-us/library/windows/desktop/ms686946 (v=vs.85).aspx

于 2012-10-13T14:12:50.317 回答
0

您可以通过在源文件中移动方法的实现来欺骗编译器,并强制它不被内联(查找编译器的特定语法)。

于 2012-10-13T14:02:39.923 回答