单元测试仅在 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 硬件中工作正常。
我正在为 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 硬件中工作正常。