2

我对 std::async 正在启动的进程有一些问题。

class BaseClass {
public:
    BaseClass() {enabledFlag = false;}
    virtual ~BaseClass() {}

protected:
    int process();
    bool enabledFlag;
};


int BaseClass::process() {
    int rc = -1;
    if (enabledFlag == false) {
      std::cout << "Not enabled\n" << std::flush;
      return rc;
    }

    rc = 0;
    while (enabledFlag) {
      // this loop should set rc to be something other than zero if an error is to be signalled
      // otherwise loop here doing stuff until the user sets enabledFlag=false
    }

    return rc;
}

class DerivedClassWithExposedMembersForTesting : public BaseClass {
public:
  using BaseClass::enabledFlag;
  using BaseClass::process;

};

在我的谷歌测试测试中:

TEST(FixtureName, process_exitsWithRC0_WhenEnabledFlagSetTrueDuringExecution {
    DerivedClassWithExposedMembersForTesting testClass;
    testClass.enabledFlag = true;

    // print status
    std::cout << "Enabled: " <<  testClass.enabledFlag << std::endl << std::flush;

    std::future<int> returnCodeFuture = std::async(std::launch::async, &DerivedClassWithExposedMembersForTesting::process, &testClass);  // starts background execution
    // set flag to false to kill loop
    testClass.enabledFlag = false;

    int rc = returnCodeFuture.get();

    EXPECT_EQ(0, rc);
}

我对 std::async 的理解是它应该安排在调用 async 后不久运行,如果线程没有完成,执行的主线程将在 get() 调用处阻塞。对 get() 的调用将返回 process() 的返回值。

如果未启用 testClass,则 process() 设置为不运行,因此我在测试中启用它。

我希望看到:

Enabled: 1
// test passes

我看到的是:

Enabled: 1
Not enabled
// test fails
Failure
Value of: rc
  Actual: -1
  Expected: 0

为什么 std::async 触发的进程没有看到主进程在进行异步调用之前设置的 enabledFlag 的值?

注意: enabledFlag 应该从外部进程设置,而不是通常从循环内部设置,因此这种构造

** 更新 ** 根据我的评论,我在调用 async() 之后通过在测试中添加以下行来修复它:

// Use wait_for() with zero milliseconds to check thread status; delay until it has started
while (returnCodeFuture.wait_for(std::chrono::milliseconds(0)) == std::future_status::deferred) {}
4

1 回答 1

1

问题是您不知道线程何时运行。可能您只是false在线程实际运行之前将标志设置为。

解决此问题的一种简单方法是isRunning在循环内设置另一个状态变量 。您的主线程可以检查这一点以了解线程何时运行,然后告诉它结束。

于 2014-09-12T13:07:09.737 回答