Unit testing 一个单元在哪个级别测试无锁代码?
是否可以使用或类似方法在开源平台上对无锁并发代码进行单元测试?有人做到了吗 如果你回答我,我不介意,但我提到LLVM、QEMU和其他,因为它们在不同的级别上起作用。我想了解在单元测试控制下交错线程的实际成功程度 我顺便知道。这是一个很好的软件,但是不能像我所知道的那样,将C++、Rust等编译成一个Sp/Pro Mela目标。 如果您知道任何关于无锁并发代码的现有开源单元测试的例子,您将非常乐意收到。(如果我知道该去哪里找,我会把资料拿来研究。) (另请参见及其答案。) 示例 据我所知,我的问题不需要一个例子,所以你可以忽略这个例子。但是,如果一个可测试的无锁代码的例子有助于讨论的目的,这里是C++中一个相对简单的玩具例子。我没有单元测试Unit testing 一个单元在哪个级别测试无锁代码?,unit-testing,llvm,open-source,qemu,lock-free,Unit Testing,Llvm,Open Source,Qemu,Lock Free,是否可以使用或类似方法在开源平台上对无锁并发代码进行单元测试?有人做到了吗 如果你回答我,我不介意,但我提到LLVM、QEMU和其他,因为它们在不同的级别上起作用。我想了解在单元测试控制下交错线程的实际成功程度 我顺便知道。这是一个很好的软件,但是不能像我所知道的那样,将C++、Rust等编译成一个Sp/Pro Mela目标。 如果您知道任何关于无锁并发代码的现有开源单元测试的例子,您将非常乐意收到。(如果我知道该去哪里找,我会把资料拿来研究。) (另请参见及其答案。) 示例 据我所知,我的问题
#include <atomic>
#include <thread>
#include <cstdlib>
#include <iostream>
const int threshold = 0x100;
const int large_integer = 0x1000;
// Gradually increase the integer to which q points until it reaches the
// threshold. Then, release.
void inflate(std::atomic_bool *const p_atom, int *const q)
{
while (*q < threshold) ++*q;
p_atom->store(true, std::memory_order_release);
}
int main()
{
std::atomic_bool atom{false};
int n{0};
// Dispatch the inflator, letting it begin gradually, in the background, to
// inflate the integer n.
std::thread inflator(inflate, &atom, &n);
// Waste some time....
for (int i = large_integer; i; --i) {}
// Spin until the inflator has released.
{
int no_of_tries = 0;
while (!atom.load(std::memory_order_acquire)) ++no_of_tries;
std::cout << "tried " << no_of_tries << " times" << std::endl;
}
// Verify that the integer n has reached the threshold.
if (n == threshold) {
std::cout << "succeeded" << std::endl;
}
else {
std::cout << "failed" << std::endl;
std::cerr << "error" << std::endl;
std::exit(1);
}
inflator.join();
return 0;
}
#include(6MB PDF),很好地解释了Peter提到的C++11并发模型。见A节。4.7.1
德克·赫尔曼的调查
@DirkHerrmann提出了一个相关问题:
您询问如何对代码进行单元测试,但我不确定您所描述的是真正的单元测试场景。这并不意味着您不能使用任何所谓的单元测试框架(实际上,它可以用于所有类型的测试,而不仅仅是单元测试)。你能解释一下你测试的目标是什么,也就是说,你想检查代码的哪些属性吗
你的观点很正确。我测试的目标是在C++11并发模型支持的所有可能的计时中,可靠地通过坏代码。如果我知道代码不好,那么我应该能够编写一个单元测试来通过它。我的问题是:
- 无线程。如果代码是无线程的,我通常可以编写一个单元测试来测试错误代码
- 线程化。要想不及格,线程化代码更难,但只要互斥体协调线程化,至少代码在不同的硬件上运行是类似的
- 无锁。要想不及格,在特定硬件上可能无法使用无锁代码。如果我糟糕的、无锁的代码在你的硬件上十亿分之一失败,而在我的硬件上却从未失败,那该怎么办?一个单元如何测试这样的代码
我真的不知道我需要什么。由于我的x86CPU没有提供真正的C++11并发模型,也许我需要一个模拟器来模拟一个不存在的CPU,它确实提供了一个真正的C++11并发模型。我不确定
如果我确实为一个不存在的CPU提供了一个仿真器,它提供了一个真正的C++11并发模型,那么我的单元测试(据我所知)将需要在所有可能的合法时间下尝试我的代码
这不是一个容易的问题。我不知道是否有人解决了这个问题
更新:CDSCHECKER和RELACY
讨论让我调查了各种来源,包括
- Norris和Demsky开发的开源软件;及
- Vyukov的开源软件,前面讨论过
在写这篇文章时,我不知道这些是否回答了我的问题,但它们看起来很有希望。我将它们链接到这里以供参考和进一步调查
为了参考的完整性,我还添加
上面已经链接了。有趣的问题
一个单元在哪个级别测试无锁代码
令人不满意的答案是:您无法真正测试您所称的“无锁并发代码”
不,等等,当然你可以:用一张纸和一支笔来测试它。试着证明它是正确的。设计级别是测试多线程代码的正确级别
当然,您可以为代码编写单元测试,而且您确实应该这样做,但实际上没有办法实现对所有可能并发执行场景的100%覆盖率
您可以(也应该)尝试折磨您的代码,在不同的体系结构上运行它(例如,x86是如此一致,它将隐藏许多并发问题。另外,在ARM上运行它)。您仍然无法找到所有错误
基本规则是:您不能使用测试来确保多线程代码的任何质量级别(无锁或带锁)。100%保证正确性的唯一方法是正式证明代码的正确性,这通常意味着您有一个非常简单的线程设计,这非常明显,每个人都能在5分钟内理解它。然后编写相应的代码
别误会我的意思:测试很有用。但多线程处理却毫无用处
为什么会这样?首先,单元测试方法不起作用:互斥体不组合
当您将100%正常工作的多线程子系统A和B组合在一起时,结果根本不能保证工作。互斥体不构成。条件变量不组合。线程之间的不变量不能组合。只有很少且非常有限的原语,比如线程安全队列,它们组成了一个完整的队列。但在单元测试中孤立地测试方面是假设事物是由函数或类组成的。有趣的问题。有些情况下,某些源代码使用任何合理的编译器编译到安全的x86 asm,但对于弱顺序的ISA来说是不安全的,这些ISA通常也能够执行原子RMW,而无需使用完整的seq cst内存屏障(对于运行时重排序;编译时间仍由编译器决定)。因此,您有两个独立的问题:源代码是否可移植到任意C++11系统,以及您的代码在x86上是否真正安全(如果您现在只关心这一点的话)。通常您希望编写可移植的正确代码,因为在为x86编译时通常不会花费更多的成本。@PeterCordes:Aha,是的,这就是我的意思。你