C++ 启用整个程序优化后,MSVC 2010是否会重新排序函数调用?

C++ 启用整个程序优化后,MSVC 2010是否会重新排序函数调用?,c++,multithreading,visual-c++,compiler-optimization,C++,Multithreading,Visual C++,Compiler Optimization,启用整个程序优化时,是否允许编译器对函数调用重新排序/GL开关 这不会破坏多线程环境中的代码吗 考虑以下伪代码: Thread1 { numbers.append( 1 ); numbers.append( 2 ); numbers.append( 3 ); numbers.append( 1 ); numbers.append( 2 ); numbers.append( 3 ); manager.signalFinished(); } Thread2 {

启用整个程序优化时,是否允许编译器对函数调用重新排序/GL开关

这不会破坏多线程环境中的代码吗

考虑以下伪代码:

Thread1
{
  numbers.append( 1 );
  numbers.append( 2 );
  numbers.append( 3 );

  numbers.append( 1 );
  numbers.append( 2 );
  numbers.append( 3 );

  manager.signalFinished();
}

Thread2
{
  // is the compiler allowed to reorder the next two lines?

  bool isReady = manager.isFinished();
  int lastElem = numbers.getLastElement();

  if( 3 == lastElem )
  {
    if( isReady )
    {
      TerminateThread();
    }
    else
    {
      // go back to start
      continue;
    }
  }
}
我们总共有2个线程

线程1将把数字放入一个列表中,一旦完成,就会触发一个信号,表明所有数字都在列表中。 假设对于完整列表,最后一个元素始终必须是3

线程2将检查信号是否已设置,以及最后一个元素是否为3

假设所有函数都在不同的编译单元中,程序应该运行正常

如果整个程序优化能够使编译器重新排序函数调用或并行执行它们,那么这个程序很可能会被破坏。 线程2的前两行似乎与编译器无关,它们不共享互斥锁,而实际上它们是在深层逻辑上链接的

重新排序可能导致以下情况:

Thread1: numbers.append( 1 );
         numbers.append( 2 );
         numbers.append( 3 );

Thread2: int lastElem = numbers.getLastElement(); // is 3

Thread1: numbers.append( 1 );
         numbers.append( 2 );
         numbers.append( 3 );
         manager.signalFinished();

Thread2: bool isReady = manager.isFinished(); // is true
         // now TerminateThread would be invoked
         // and the second 1, 2, 3 of Thread1 would be lost

isFinished调用是否使用锁或原子?如果是,则不允许编译器在获取和加载之前向上移动读取。如果没有,那么你的程序就有数据竞争,并且表现出未定义的行为——在这种情况下,编译器可以合法地做任何事情。同样值得怀疑的是,线程2必须代表线程1做信号传递。线程2如何知道这一点?显然,线程1必须向线程2发送信号,因此线程2可以向线程3发送信号。但为什么不直接这样做呢?