从当前线程中查找活动线程的状态。 (Robust Mutexes的实现)

时间:2011-06-22 13:51:58

标签: c pthreads mutex

我们正在尝试将一些代码从Solaris移植到HPUX。虽然Solaris使用它自己的线程API,但HPUX使用Pthread API。我们在迁移过程中遇到的一个问题是,HPUX上没有实现强大的互斥锁,因为不需要实现它以保持POSIX兼容。

我们尝试使用pthread_mutex_trylock使等待队列中的线程不阻塞。我们想要一些方法来确定作为互斥锁所有者的线程是否存活。如何从调用线程获取该线程的状态?

提前感谢, 阿迪亚。

2 个答案:

答案 0 :(得分:2)

不幸的是,安东尼的方法有多种竞争条件:

  1. 线程获取互斥锁并将自身存储为所有者之间存在时间间隔。如果另一个线程在trylock处失败并想要检查所有者,则可能会发现所有者仍未写入。在这种情况下,它可能会等待所有者将写出其身份,但如果所有者在正确(错误)时刻死亡,等待将陷入僵局。
  2. 在所有者死亡后,可以重新分配与互斥锁一起存储的所有者标识符。请注意,只存储一个线程ID是没用的,因为线程ID在进程间并不是唯一的,而强大的互斥语义只对进程共享的互斥锁有意义。 (在一个进程中,您可以完全控制线程终止;它们无法无法预测地终止,因此您可以正确清理线程并在它们退出时释放它们的互斥锁。)如果您正在使用PID,那么您可以避免使用PID的唯一情况如果进程是您自己的子进程并且您尚未等待它,则重新分配PID。
  3. 正确实现健壮的互斥锁确实需要内核的帮助以避免竞争条件。当然,您可以使用令人讨厌的慢速技术,其中每个锁定和解锁操作都需要系统调用来模拟系统上的强健互斥体,而没有适当的类似互斥锁的强大互斥支持,例如,使用fcntl锁定或SysV信号量,两者都具有语义,通过它可以实现自动和原子解锁所有者注册......

答案 1 :(得分:1)

一般情况下,你无法判断哪些线程拥有互斥锁,不管它是否存在。

如果您想知道这些信息,那么您必须自己存储---在锁定互斥锁之后立即将线程ID存储在某处,然后在解锁互斥锁之前清除该值。这些商店必须是原子的,或者由互斥锁本身保护(显然,如果你使用互斥锁,那么你就无法检查这个互斥锁的问题,否则你会有一个递归问题)。然后,您可以使用此存储的线程ID来检查线程是否处于活动状态。

这假设(a)您的线程不会在获取互斥锁和设置所有者之间死亡,并且(b)线程ID不会被重用。它还掩盖了“检查线程是否存在”的部分---这本身并不是一件容易的事。

如果您假设线程可能在任何时候死亡,那么在没有操作系统支持的情况下构建“健壮的互斥体”实际上是不可能的。