gpt4 book ai didi

c++ - 我如何对 condition_variable::wait 周围的包装器进行单元测试?

转载 作者:行者123 更新时间:2023-11-30 05:19:25 24 4
gpt4 key购买 nike

我有一个类有一个等待队列被填满的 wait 函数。一旦队列非空,condition_variable 就会收到通知,等待函数会清空队列并处理其中的元素。

我想在单元测试中验证此 wrapper::wait 调用(检查队列是否为非空)实际上阻塞了线程。我有一个不稳定的设置,其中包含一个 atomic_bool,它是在 wait 调用之后设置的,我天真地认为执行以下序列会起作用。

  1. 使用调用wait 的函数创建线程,然后设置atomic_bool
  2. 创建线程后,验证atomic_bool有开始值
  3. 在主线程中将某些内容插入队列,使 atomic_bool 更改其他线程的值。
  4. 在主线程中验证更改的值。

缺少两个同步点:两个“验证”不能保证在我希望它们发生时发生:

  • 我无法验证是否已在线程中调用了 wait。
  • 我无法验证线程是否有机会更改 atomic_bool

有没有什么办法可以在不增加一个或多个额外的condition_variables/mutexes来同步操作的情况下解决这个问题?

最佳答案

这真的是使用 std::condition_variable 的完美场景, 但无论如何:您可以将多个同步点与 std::atomic<int> gate 一起使用.各种值将对测试的不同阶段进行编码。等待值更改的时间超过某个恒定时间 T 将被视为测试用例失败1

  • gate == 0 : 辅助线程未初始化。
  • gate == 1 : 辅助线程已初始化,但尚未响应。
  • gate == 2 : 辅助线程已初始化并正在运行,可以假设已调用 wait .
  • gate == 3 : 主线程已向队列添加内容,辅助线程可能仍在等待。
  • gate == 4 : 辅助线程已退出 wait并设置最后一个值。

如果愿意,您可以省略几个同步点。

主线程

  1. 设置gate到 0。
  2. 生成辅助线程。
  3. 设置gate到 1。
  4. 等待 T gate变成2;失败时:“辅助线程从未达到 wait
  5. 向队列添加一些东西,设置gate到 3.
  6. 等待 T gate变成4;失败时:“辅助线程从未退出 wait
  7. 等待 T 次线程加入;失败时:“辅助线程在退出前挂起”

辅助线程

  1. 等待 T gate变成 1;失败时“主线程在产生后挂起”
  2. 设置gate到 2. 调用 wait .
  3. (调用 wait 退出;队列已处理)。
  4. 等待 T gate变成3;失败时“回到过去”
  5. 设置gate到 4 并退出。

要实现“等待和检查”部分,您可以使用 compare_exchange std::chrono .一个可能的实现可能是这样的:

#include <atomic>
#include <chrono>
#include <condition_variable>

std::cv_status wait_till_reaches(
std::atomic<int> &gate,
std::chrono::high_resolution_clock::duration const &rel_time,
const int desired_value,
bool increment = false
) {
const int next_value = desired_value + (increment ? 1 : 0);
int dummy = desired_value;
const std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
while (not gate.compare_exchange_weak(dummy, next_value)) {
dummy = desired_value;
if ((std::chrono::high_resolution_clock::now() - start) >= rel_time) {
return std::cv_status::timeout;
}
}
return std::cv_status::no_timeout;
}

1 这不是测试准确您的代码是否工作,而是测试它是否工作足够快,但另一方面,如果您有一些线程问题,也不能保证测试用例会捕获它(在某些时候,您必须决定等待响应的时间)。

关于c++ - 我如何对 condition_variable::wait 周围的包装器进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41131112/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com