如何知道线程是否处于死锁状态?

如何知道线程是否处于死锁状态?

问题描述:

我创建了两个用C代码编写的线程,它在Linux操作系统上运行。这两个线程都在做一些工作,并且它的父进程还在运行时会永久运行。如何知道线程是否处于死锁状态?

创建这些线程的过程是以一定的时间间隔向systemd发送一个看门狗通知。但是,在发送看门狗通知之前,它想要检查所有线程是否处于非死锁状态。

在代码中可以使用哪种系统调用,或者可以使用哪种机制来知道线程不处于死锁状态,以便进程可以检查其创建的线程是否处于死锁状态,并且只发送如果所有线程都处于非死锁状态,则向systemd发送看门狗通知。

+1

当线程即将获取系统资源时,为父线程存储时间戳。当线程获取系统资源时,使时间戳无效。如果父线程看到时间戳超过某个限制,它可以声明系统已死锁。 – user3386109

+0

通过为父线程存储时间戳,你的意思是什么?父线程如何知道该子线程即将获取系统资源。请您分享一个示例示例来实现我的目标 –

+0

操作系统无法以任何有效的方式确定此示例。您需要在您的应用设计中进行这样的检查,如果您需要,可以设计它,并且如果可以实现它,而不会引入比解决问题更多的问题。 –

最简单的方法是让每个需要跟踪的线程定期更新自己的共享变量。监控包括检查共享变量的值是否经常变化。

考虑一个类比。你经常不在家,但你想确保你的两个孩子没有失踪。所以你每个孩子都有一个罐子。你告诉他们每次回家时都要给罐子加一分钱。现在,每次你回家的时候,你都会在每个罐子里计数几分钱。如果任何孩子的罐子的硬币数量相同时间过长,则知道您有问题。

因此,举例来说,你可以修改每个线程做的工作:

  1. 做一些工作。
  2. 转到1

要:

  1. 做一些工作。
  2. 递增我的进度变量。
  3. 转到步骤1

则监控线程只是要跟踪它最后一次看到了状态变量和当前值不同的值。然后,它可以按如下方式检测死锁线程:

  1. 在我们正在监视的每个线程上循环。
  2. 其状态变量是否与上次不同?如果不是,请转至步骤5.
  3. 存储我们看到的其状态变量的值并存储当前时间。
  4. 继续我们在步骤1中开始的循环。
  5. 我们为此线程的上次更新存储了过去的时间吗?如果是这样,报告一个僵局。
  6. 继续我们在步骤1中开始的循环。
+0

我认为第二宗案件适用于部分案件。让我们假设,线程调用select in loop并且线程处于阻塞状态。只有选择获取信号,然后只有'状态变量'被更新,它才会继续循环。正在以某个间隔监视此线程的主线程将获得旧状态变量值,因为在主线程正在检查状态变量的那个时间间隔内没有触发select,因为主线程检查它保留了旧值,但它报告了死锁线程不处于死锁状态。 –

+0

@VikashRanjan您必须在'select'中设置合适的超时时间。否则,将一个管道末端添加到'select'集合并让监视线程使用它来触发。是的,这必须嵌入到设计中 - 它不会随意洒在顶部。 –

+0

@VikashRanjan阅读我的答案。这正是我所解释的。设计线程以便每隔一段时间递增一个状态变量,如果它没有改变,则会死锁。 –