C# 如何以线程安全的方式检查一个线程和另一个线程的状态?
背景: 在调试应用程序时,我遇到了这个函数C# 如何以线程安全的方式检查一个线程和另一个线程的状态?,c#,multithreading,C#,Multithreading,背景: 在调试应用程序时,我遇到了这个函数 boolean IsThreadGood(Thread t) { return t.IsAlive && t.ThreadState == ThreadState.Running || t.ThreadState == ThreadState.WaitSleepJoin; } 我认为这是一个bug,因为return语句中发生的逻辑比较不是原子的,因此我认为线程t可能在执行表达式时改变状态。为了验证这一想法,我将代码更改为以下代
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的ThreadState为WaitSleepJoin,当我将代码转到下一个if语句时,线程t的状态已切换,ThreadState为Running,因此测试失败,并在返回true时从方法返回false
我的问题:
如何以线程安全的方式从另一个线程检查线程的状态
我的想法和我的研究:
我不是多线程专家,因此如果我的任何假设不正确或我对多线程的理解不正确,请随时指出。我非常确定,状态为运行的线程或状态为WaitSleepJoin的线程不可能处于活动状态。因此,您可以只获取状态(这是一个原子操作),然后对照这两个值进行检查:
boolean IsThreadGood(Thread t)
{
ThreadState state = t.ThreadState;
return state == ThreadState.Running || state == ThreadState.WaitSleepJoin;
}
请注意,明确指出您应该仅将线程状态用于调试目的,而不用于同步:
线程状态只对调试场景感兴趣。您的代码不应该使用线程状态来同步线程的活动
由于您对原子操作感兴趣,我怀疑您是否希望将其用于调试目的(否则您就不必关心它的超精确性)。因此,您可能应该考虑以不同的方式解决实际问题。方法线程。Join(int毫秒计时)
可用于安全地测试线程是否已完成。当线程不再处于活动状态时,它返回true
// 0 == don't wait.
if (thread.Join(0))
{
// remove thread from the list
}
由于明显的原因,应该从另一个线程调用它。这永远不会工作。该线程可能处于其最后一条指令,您的检查将错过最近的保证退出。线程必须与您配合。您需要在更高级别上进行同步。我不知道该怎么做,因为我不知道该应用程序的功能。问一个新问题,详细说明和代码 请注意,
t.IsAlive&&t.ThreadState==ThreadState.Running | | t.ThreadState==ThreadState.WaitSleepJoin
忽略了|
操作符周围的大括号。这并不重要,因为这段代码必须扔掉
state==ThreadState.WaitSleepJoin
应该完成什么?这种状态可能是错误的,因为许多库可能会进入这种状态。这一切似乎都是假的
作为一种解决方法,您可以实现一个看门狗线程:
while (true)
DetectExit();
Sleep(100);
如果线程在检查“goodness”的所有点上都是“good”,则当前函数返回true。我不确定找到一个原子解决方案是否有意义,如果确实存在的话,因为在函数返回true后,线程可能会立即变得不好。假设此代码用于已知线程不会以任何频率从好切换到不好的场景。
var state=t.ThreadState;返回状态==ThreadState.Running | | state==ThreadState.WaitSleepJoin代码>@Eric J该方法用于删除队列中未运行的线程。如果该方法在队列中留下一个未运行的线程,这是正常的,因为它将在下次该方法运行时被删除。但是试图删除一个仍在运行的线程会导致问题,那么当前的代码就应该可以了。它必须通过所有“良好”检查才能被视为“良好”。如果它没有通过任何一次检查,它将不会运行,也不会自行返回到运行状态。您可能需要考虑依赖于框架提供的工具——即,带有异步/等待的任务可能是合适的。请注意,在将线程分配给本地变量<代码>状态< /代码>之后,线程的真实状态可能会发生改变。方法调用IsThreadGood不是原子的,从指示返回语句处线程的真实状态的意义上讲。然而,根据OP对问题注释中如何使用代码的描述,这并不重要。这并不能解决问题。他已经可以检测到一个已经结束的线程。他已经尽可能可靠地检测到一个线程退出。问题是,线程可以在检查后立即退出。只有在检测到退出时,该检查才有意义。@OP中的usr IsThreadGood()在状态从WaitSleepJoin切换到Running时可能会错误地返回false。我明白了。好的,让我们等待OP的回应,看看他的问题到底是什么。也许这就是他要找的。回答得好。