单元测试仅在 ARM 中失败

Unit tests fail only in ARM

我正在为 Raspberry Pi 开发一个多线程程序,我注意到我们当前的代码 运行 在我的电脑和其他学院的电脑上都完美无缺,但是当运行宁在 ARM 上。

我们的项目使用 C++11,这是我们计算机中的输出:

............ Success! Test run complete. 12 tests run. 12 succeeded.

但是当我们尝试在 ARM 上 运行 它时,正如您在此处看到的那样:https://travis-ci.org/OpenStratos/server/builds/49297710

内容如下:

.... No output has been received in the last 10 minutes, this potentially indicates a stalled build or something wrong with the build itself.

经过一番调试,我了解到问题出在这段代码上:https://github.com/OpenStratos/server/blob/feature/temperature/serial/Serial.cpp#L91

this->open = false;
while( ! this->stopped);

还有另一个线程做相反的事情:

while(this->open)
{
    // Do stuff
}
this->stopped = true;

当我需要停止线程时调用第一个代码,并且使用双标志让线程即使在停止时也能够更新当前对象。这两个变量都是 std::atomic_bool 类型,但似乎在 while ( ! this->stopped); 中它不检查它,它假设一个 while (true);.

是这样吗?如何解决?为什么它在我的 x86_64 处理器上与在 ARM 上的工作方式不同?

提前致谢。

std::atomic<T>做出的核心保证就是你永远可以读到一个值。不一定保证一致性。

现在,在这种情况下,您依赖于 .operator bool,它相当于 .load(memory_order_seq_cst)operator=(x),相当于 .store(x, memory_order_seq_cst)。这应该给你一个顺序一致的内存顺序。

你在 ARM 上观察到的顺序对我来说是顺序一致的。你还没看到stopped == true的禁食就可以了。没有时间限制。编译器不能将内存操作与另一个内存操作交换,但它可能会无限期地延迟它。

主要问题是为什么这个线程应该完全停止。如果在该线程的循环体中完成了任何真实的、可观察到的工作,则该循环体不能相对于 stopped==true 检查重新排序。

最后的问题是我在 Travis.ci 中创建的环境无法正常工作。在真正的 ARM 硬件中工作正常。