【问题标题】:How to manage a shared POSIX semaphore with async signals in a multithreaded application如何在多线程应用程序中使用异步信号管理共享 POSIX 信号量
【发布时间】:2012-09-05 10:31:03
【问题描述】:

我必须编写一个线程安全库,该库使用 POSIX 信号量(用作初始值 = 1 的互斥量)进行同步。我发现了一些正确管理异步信号的问题。我有一个链接到这个静态库的应用程序,并且应用程序(多线程)调用库的函数。对某些内部结构的访问由 posix 信号量控制(它在库内部):

void library_func1(lib_handler *h)
{
   sem_wait(sem);
   /* do some stuff with global data */
   sem_post(sem);
}

void library_func2(lib_handler *h)
{
   sem_wait(sem);
   /* do some stuff with global data */
   sem_post(sem);
}

void library_close(lib_handler *h)
{
   ...
}

如果在一个线程锁定信号量时引发了一个异步信号,比如说SIGINT,会附加什么?如果我重新启动应用程序,我将遇到死锁,因为信号量存在并且它的值为0。有一个函数library_close 可以在引发异步信号时释放信号量,但这是最好的检查方法(我认为只有在exit 之后,该函数才是信号安全的)?在多线程应用程序中,对所有信号使用单个线程管理器通常是一个好习惯:该线程应该在库中还是可以在应用程序中启动它?

谢谢大家。

【问题讨论】:

    标签: linux multithreading signals async-safe


    【解决方案1】:

    Linux futex 也有同样的问题。它不是完全可解决的,但您可以做的是编写进程的 pid,将信号量锁定在同一共享内存区域的某处。如果另一个进程试图锁定信号量并且花费的时间太长(对于某些“太长”值),它会通过从共享内存中读取 pid 来找出哪个进程锁定了信号量。如果该进程不再存在,您就知道您处于死锁状态(您可能应该死掉,因为库的内部数据可能处于不一致的状态)。

    这仍然存在一个小竞争,因为获取锁的进程可能会在锁定之后但在写入其 pid 之前死亡。 AFAIK 没有办法使用信号量来避免这种情况。 (如果您有一个锁实现,其中 pid 在获取时以原子方式写入锁变量,它可能会起作用,但您可能需要自己编写。)

    【讨论】:

      【解决方案2】:

      静态库的状态不会在应用的不同运行之间转移,也不会被使用它的其他应用共享。它是使用它的应用程序状态的一部分。所以你的信号量不会处于不稳定状态。

      【讨论】:

      • 信号量在应用程序之间共享。
      • 怎么样?你在使用某种类型的进程间通信方案吗?
      • 一个 POSIX 信号量可以通过例如/dev/shm 访问,因此在进程之间共享。
      猜你喜欢
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-23
      • 1970-01-01
      • 1970-01-01
      • 2011-02-04
      相关资源
      最近更新 更多