我遇到了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;
};
在我的Google测试中:
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的理解是它应该被调度在调用异步后不久运行,并且如果线程还没有完成,则执行的主线程将在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) {}
答案 0 :(得分:1)
问题是,当线程运行时,您不知道。可能是您在线程实际运行之前将标志设置为false
。
解决此问题的一种简单方法是使用另一个状态变量isRunning
,该线程在循环内设置。您的主线程可以检查此线程以了解线程何时运行,然后告诉它结束。