【问题标题】:Finding out statuses of active threads from the current thread. (Implementation of Robust Mutexes)从当前线程中找出活动线程的状态。 (鲁棒互斥体的实现)
【发布时间】:2011-06-22 13:51:57
【问题描述】:

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

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

提前非常感谢, 阿迪亚。

【问题讨论】:

  • +1 个有趣的问题。我认为最好的答案是“你不能有效地解决问题”,但我试图提供一些原因和潜在(低效)的解决方法。

标签: c pthreads mutex


【解决方案1】:

不幸的是,Anthony 的方法有多个竞争条件:

  1. 线程获取互斥锁和将自身存储为所有者之间存在时间间隔。如果另一个线程在 trylock 失败并想要检查所有者,它可能会发现所有者仍未写入。在这种情况下,它可以等待,希望所有者写下它的身份,但如果所有者在正确(错误)的时刻死亡,等待将陷入僵局。
  2. 与互斥锁一起存储的任何所有者标识符都可以在所有者去世后重新分配。请注意,仅存储线程 id 是没有用的,因为线程 id 在进程之间不是唯一的,并且健壮的互斥体语义仅对进程共享的互斥体有意义。 (在单个进程中,您可以完全控制线程终止;它们不能意外终止,因此您可以让线程正确清理并在它们退出时释放它们的互斥锁。)如果您使用的是 PID,唯一可以避免的情况是重新分配 PID 是指该进程是您自己的子进程并且您还没有等待它。

稳健的互斥锁的正确实现确实需要内核的帮助以避免竞争条件。当然,您可以使用令人讨厌的慢速技术,其中每个锁定和解锁操作都需要系统调用来模拟系统上的健壮互斥锁,而没有适当的类似 futex 的健壮互斥锁支持,例如使用 fcntl 锁定或 SysV 信号量,它们都具有可以实现自动和原子解锁所有者注册的语义...

【讨论】:

    【解决方案2】:

    通常,您无法分辨哪些线程拥有互斥锁,更不用说它是否处于活动状态。

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

    这假设 (a) 您的线程不会在获取互斥锁和设置所有者之间死亡,并且 (b) 线程 ID 未被重用。它还掩盖了“检查线程是否处于活动状态”部分——这本身并不重要。

    如果您假设线程可能在任何时候死掉,那么如果没有操作系统支持,构建“强大的互斥锁”实际上是不可能的。

    【讨论】:

    • 但是保护线程 ID 的互斥体需要自己的线程 ID...
    • @Nemo:还有更深层次的问题。看我的回答。
    猜你喜欢
    • 2014-10-03
    • 2016-12-27
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2013-01-31
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多