C++ 异步竞争条件还是错误?

C++ 异步竞争条件还是错误?,c++,asynchronous,std,C++,Asynchronous,Std,我试图使用atomic_bool打破std::async,代码结构如下所示 class Test { atomic_bool IsStopped; std::future <void> Future; Test () : IsStopped (false); { LogValueWithMutex (IsStopped); Future = std::async (std::launch::async

我试图使用atomic_bool打破std::async,代码结构如下所示

class Test
{
   atomic_bool          IsStopped;
   std::future <void>   Future;

   Test ()
     : IsStopped (false);
   {
      LogValueWithMutex (IsStopped);

      Future = std::async (std::launch::async, &Test::AsyncFunction, this);
   }

   ~Test ()
   {
     LogValueWithMutex (IsStopped);

     IsStopped = true;

     if (Future.valid ())
       Future.get ();
   }

    void AsyncFunction ()
    {
      while (1)
      {
        // only read atomic_bool, does not write
        if (IsStopped)
          break;
      }
    }

    void CallbackFromNetworkWhichIsNotImportant ()
    {
      // Bug here!! On 2nd entry, this value is set to true! In Both Debug/Release Mode
      LogValueWithMutex (IsStopped);

      if (! IsStopped)
      {
        IsStopped = true;

        if (Future.valid ())
          Future.get ();

         // call an API which exit and will destroy this class
      }
    }
}
类测试
{
原子布尔;
std:未来;
测试()
:i(假);
{
具有互斥的LogValueWithMutex(IsStopped);
Future=std::async(std::launch::async,&Test::async函数,this);
}
~Test()
{
具有互斥的LogValueWithMutex(IsStopped);
IsStopped=true;
if(Future.valid())
Future.get();
}
void异步函数()
{
而(1)
{
//只读原子布尔,不写
如有(见附件)
打破
}
}
无效从不重要的网络调用()
{
//这里有Bug!!在第二个条目中,这个值被设置为true!在调试/发布模式下
具有互斥的LogValueWithMutex(IsStopped);
如果(!IsStopped)
{
IsStopped=true;
if(Future.valid())
Future.get();
//调用退出并将销毁此类的API
}
}
}
只要异步能正常中断,一切都能正常工作。然而,在VS2015中第二次创建该类时,从Network调用LogValueWithMutex,这并不重要。我已经验证了它的日志输出

Test ctor IsStopped: 0
Test CallbackFromNetworkWhichIsNotImportant: 0
Test dtor IsStopped: 1
Test ctor IsStopped: 0
Test CallbackFromNetworkWhichIsNotImportant: 1 <- Wrong! Who is setting this to true??!!
Test dtor IsStopped: 1
测试:0
来自网络的测试调用,该调用不重要:0
测试数据类型:1
测试时间:0

来自网络的测试调用不重要:1缺少代码的用法。然而,我相信有一些多线程正在那里进行。多线程处理很棘手,很容易陷入“竞争条件”,即事情的顺序很重要,在某些情况下可能变得不符合预期

为了调查您的故事,我创建了一个简单的用法,可以重现您意外的输出。你不一定会有和我在下面创建的完全相同的场景,可能会有其他类似的比赛条件。复制意外输出的代码是错误的(对象在一个线程中被删除,而在另一个线程中仍在使用),但类似的错误可能会发生在多线程程序中。在你的代码中寻找这样一个bug。。。(除非您对随机字符串解决方案满意:-)

以下是我得到的输出: 主要有以下几点:
可能是该对象从两个不同的地方被销毁了两次。

我发现了问题。这与异步或原子布尔无关(这是我第一次尝试)。我根据“this”分配了一个回调,但只执行了一次,所以当我再次新建该类时,它正在现有实例上使用(因此内存已损坏)。使用原子布尔来打破循环的多线程处理工作得很好。很抱歉出现了误报。

我没有理解问题的地方是启动
测试
类的代码。我正在使用cocos2dx,它是一个状态机,用于处理应用程序状态,类似于此,它将管理新建/删除并选择要运行的状态(类)。我在状态之间切换。变量中的一个值从未设置,然后插入另一个变量,然后它突然工作。。。这种行为的原因通常是越界访问或写入野生指针,或写入调用中遗漏的参数。(好的,如果你没有疯狂函数指针的转换,那么C++中就不应该发生后者。)
class Test
{
   atomic_bool      IsStopped;
   std::future <void>   Future;
   std::string      RandomString; // HERE IS A TEST
   Test ()
     : IsStopped (false);
   {
        // NEW CODE
        ostringstream oss;
        oss << rand ()% 100;
        RandomStringToTestInstance = oss.str ();

        LogValueWithMutex (IsStopped);

        Future = std::async (std::launch::async, &Test::AsyncFunction, this);
   }
       // all parts unchanged
}

Test ctor IsStopped: 0
Test CallbackFromNetworkWhichIsNotImportant: 0
Test dtor IsStopped: 1
Test ctor IsStopped: 0
Test CallbackFromNetworkWhichIsNotImportant: 0 <- Correct!!
Test dtor IsStopped: 1
case 1:
Test::Test(): IsStopped = 0
void Test::CallbackFromNetworkWhichIsNotImportant(): IsStopped = 0
Test::~Test(): IsStopped = 1
case 2:
Test::Test(): IsStopped = 0
void Test::CallbackFromNetworkWhichIsNotImportant(): IsStopped = 1
Test::~Test(): IsStopped = 1
int main() {
    // OK scenario
    {
        cout << "case 1:" << endl;
        Test t;
        t.CallbackFromNetworkWhichIsNotImportant();
    }

    // Bad scenario
    std::this_thread::sleep_for(1s);
    cout << "case 2:" << endl;
    Test* tp = new Test();
    // here the error is quite verbose, but the same can be more hidden in the code
    std::thread th(&Test::CallbackFromNetworkWhichIsNotImportant, std::ref(*tp));
    delete tp;
    th.join();
}
// call an API which exit and will destroy this class