【发布时间】:2021-03-24 23:44:34
【问题描述】:
我正在为多线程系统编写一组单元测试。我想编写一个测试,确认线程 B 被线程 A 阻塞。我当前的解决方案(我知道这是不正确的)是让线程 A 休眠一段时间,然后让主线程确定线程 B至少花了那么长时间才能完成。我意识到这个测试并不是真的有效,因为线程 B 可能只是被系统调度出来并且需要很长时间才能运行,这与被阻塞无关。
更多信息,基于 cmets:
我不能详细说明,但是 $dayjob 已经实现了自己的任务线程系统,与例如没有太大不同。 Android 的 AsyncTask 和我的任务是(明白吗?)为它编写单元测试。我已经编写了十几个我很满意的单元测试,并且满意是完全确定的。但是只有几个单元测试让我望而却步。在少数情况下,线程需要等待特定条件,我需要确认它实际上是在该条件下被阻塞的,而不是碰巧在错误的时间休眠。
我提出的测试不会产生任何错误的失败,但如果调度程序碰巧在错误的时间让线程进入睡眠状态,仍然可能产生错误的成功。
还有更多信息:我不是在测试使用线程库的代码,而是在测试库本身。
【问题讨论】:
-
“阻塞”就像“等待锁”还是什么?
-
根据经验,从来没有发现这样的测试要求是必要或有用的——如果线程卡住或循环,通常很明显。 TBH,在多线程和/或分布式系统上,我从来没有发现单元测试作为一个整体是必要或有用的:) 我担心任何这样的工具都会引入比它所能解决的更多的问题,但显然我有没有经历过每一个测试环境。我不羡慕你,祝你好运...:)
-
在某些全局数据或其他数据需要受保护访问的情况下,大多数操作系统都提供带有超时的锁定等待,因此线程很容易检测到疯狂的锁定等待并抱怨它,(例如,带有合适的日志消息)。这样的代码通常可以留在系统测试中,甚至可以交付,构建没有性能损失,因此 QA 不能抱怨交付的构建不是经过测试的构建:)
-
'然后由主线程来确定'....是的,我担心你的设计正在接近一个没有足够引擎动力逃逸的事件视界。像“完成”这样的短语让我担心,我希望你已经设法避免了“创建/终止/加入”线程设计的超大质量黑洞,正如 umm 所鼓励的那样......“低于最佳”pthread 等库:)
-
一般意义上的“被阻止”。一个测试在同一个线程队列上启动了两个任务,我想确认第二个任务直到第一个完成才运行。另一项测试确认任务在互斥体上等待。另一个线程在条件变量上等待。
标签: c++ multithreading unit-testing synchronous