背景:
在调试一个应用程序时,我遇到了这个函数
boolean IsThreadGood(Thread t)
{
return t.IsAlive && t.ThreadState == ThreadState.Running || t.ThreadState == ThreadState.WaitSleepJoin;
}
我认为这是一个bug,因为return语句中的逻辑比较不是原子操作,所以我认为线程t在表达式执行时可能会改变状态。为了检查这个想法,我将代码更改为以下代码,以便我可以设置断点:
bool IsThreadGood(Thread t)
{
if (t.IsAlive)
{
if (t.ThreadState == ThreadState.Running)
{
return true;
}
if (t.ThreadState == ThreadState.WaitSleepJoin)
{
return true;
}
}
return false;
}
我在内部if语句上放置了断点,很快就发现了我怀疑的问题。当代码到达第一个断点时,线程t的线程状态为WaitSleepJoin,当我跨越代码到下一个if语句时,线程t已经切换了状态,并且具有Running的线程状态,因此未通过两个测试并从方法返回false,而它应该返回true。
我的问题:
如何以线程安全的方式从另一个线程检查线程的状态?
我的想法和我所研究的内容:
如果我可以使语句原子化,那么它将起作用。我谷歌了一些关于“如何在c#中使语句原子化”的东西,得到了许多涉及锁定的结果 - 这不是我想要的,因为据我所知,锁定不能使代码原子化。
如果我可以从执行该方法的线程中暂停Thread t,那么我就可以安全地检查它的状态。我在这里找到的是已过时的函数Suspend和Resume。Microsoft强烈建议不使用这些函数。
以某种方式更改Thread t以实现同步。这不是一个选项。该代码是可重复使用的代码,已被不同的客户以不同的方式重用,而Thread t是客户端代码。更改所有客户端将是不可能的。
我不是多线程专家,因此如果我的假设不正确或我的多线程理解不正确,请随时指出。
var state = t.ThreadState; return state == ThreadState.Running || state == ThreadState.WaitSleepJoin;
- Blorgbeard