最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

单元测试线程:如何确认线程被阻塞

网站源码admin23浏览0评论
本文介绍了单元测试线程:如何确认线程被阻塞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我正在为多线程系统编写一组单元测试.我想写一个测试,确认线程 B 被线程 A 阻塞.我目前的解决方案,我知道是不正确的,是让线程 A 休眠一段时间,然后让主线程确定线程 B至少花了那么长时间才能完成.我意识到这个测试并不是真的有效,因为线程 B 可能只是被系统调度了,并且需要很长时间才能运行,这与被阻塞无关.

I'm writing a set of unit tests for a multi-threaded system. I want to write a test the confirms that thread B was blocked by thread A. My current solution, which I know isn't correct, is for thread A to sleep for a while, and then for the main thread to determine that thread B took at least that long to complete. I realize that this test isn't really valid because thread B could have simply been scheduled out by the system and took a long time to run that had nothing to do with being blocked.

更多信息,基于评论:

我无法详细说明,但是 $dayjob 已经实现了自己的任务线程系统,与例如Android 的 AsyncTask 和我的任务是(明白了吗?)为它编写单元测试.我已经编写了十几个我很满意的单元测试,并且满意是完全确定的.但是只有几个单元测试让我望而却步.有几种情况,一个线程需要等待一个特定的条件,我需要确认它实际上是在这个条件下阻塞的,而不是恰巧在错误的时间休眠.

I can't go into the details, but $dayjob has implemented its own task threading system not too different from e.g. Android's AsyncTask and I've been tasked (get it?) with writing the unit tests for it. I've written a dozen or so unit tests which I'm happy with, and satisfied are completely deterministic. But just a few unit tests elude me. There are a few cases where a thread needs to wait for a specific condition, and I need to confirm that it was actually blocked on the condition and didn't just happen to sleep at the wrong time.

我提出的测试不会产生任何错误的失败,但如果调度程序碰巧在错误的时间让线程进入睡眠状态,仍然可能产生错误的成功.

The test I came up with won't generate any false failures, but could still generate false successes if the scheduler happens to put a thread to sleep at the wrong time.

还有更多信息:我不是在测试使用线程库的代码,而是在测试库本身.

Still more information: I'm not testing code that uses the threading library, I'm testing the library itself.

推荐答案

多线程代码的测试是一个非常有趣的领域,IMO.我会说你专注于太低级的事情 - 你试图检测线程 B 被线程 A 阻塞".您可能会遇到大量其他问题(竞争条件、数据竞争),例如没有用于存储/加载的适当内存屏障的共享变量.这就是为什么我更愿意在以下两个方面专注于您自己程序的功能/状态:

Testing of multithreaded code is a very interesting area, IMO. I'd say that you concentrate on too low level things - you are trying to detect that "thread B was blocked by thread A". You may have a ton of other problems (race conditions, data races) like a shared variable with no appropriate memory barriers used to store/load. That's why I'd prefer to concentrate on your own program's functionality/state in 2 following aspects:

在测试过程中没有达到意外状态(没有相关的错误,包括竞争条件或数据竞争)测试按预期取得进展(不会因为任何原因(包括竞争条件或数据竞争)出现意外的长时间等待/阻塞/死锁)

例如,在单生产者/单消费者队列测试的情况下,我们用 2 个线程编写一个测试.一个线程放置 N(最好 - 百万)值(数字,例如,从 1 到 N).另一个线程从队列中取出 N 个值.

For example, in the case of Single Producer/Single Consumer Queue test, we write a test with 2 threads. One thread puts N (preferable - millions) values (numbers, for example, from 1 to N). Another thread takes N values from the queue.

为了确保我们没有竞争条件或数据竞争,消费者可能会检查每个值是否等于前一个值 + 1.这就是我们检查预期状态的方式.

To make sure we don't have race conditions or data races, the consumer might check that each value equals to the previous value + 1. This is how we check our expected state.

为了确保我们取得进展,生产者可能会在每次 put() 之后增加一个 PutCounter.消费者 - 每次 take() 之后的 TakeCounter.测试完成后,我们检查我们的最终进度不变PutCounter == TakeCounter == N.由于我们可能有一个影响进度的bug,我们应该在测试上设置一个合理的Timeout.

To make sure we make progress, the producer might increment a PutCounter after each put(). The consumer - a TakeCounter after each take(). After the test is finished, we check our final progress invariant PutCounter == TakeCounter == N. Since we may have a bug which affects the progress, we should set a reasonable Timeout on the test.

由于此类测试需要大量时间才能运行,因此我已在开发人员的构建中禁用它们,并且仅在启用 CI 时禁用它们.

Since such tests require a significant amount of time to be run, I have disabled them from build on developer's side and only in CI enabled.

至于您的特定情况,我们可能会测试测试在超时期间没有取得进展,并且仅用于调查/错误修复我们进行线程转储并查看这是因为线程 B 被线程阻塞"一个".想想每个线程应该做什么?什么是进步"?是针对每个线程还是针对整个系统?然后准备一个测试场景并通过超时验证是否达到了最终进度.

As for your particular case, we might test that the test doesn't make progress during a timeout and only for investigating/bug-fixing we make a thread dump and see that this happened because "thread B was blocked by thread A". Think about what each thread should do? What does "progress" mean for each thread or for the whole system? Then prepare a test scenario and validate with a timeout that the final progress was reached.

这篇关于单元测试线程:如何确认线程被阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

发布评论

评论列表(0)

  1. 暂无评论