2012-09-05 43 views
0

我必须编写一个线程安全的库,它使用POSIX信号量(用作具有初始值= 1的互斥量)进行同步。我发现一些问题来正确管理异步信号。我有一个应用程序链接到这个静态库和应用程序(多线程)调用库函数。访问一些内部结构是由POSIX信号控制(这是内部的库):如何在多线程应用程序中用异步信号管理共享的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,该函数才会是信号安全的)?在多线程应用程序中,对于所有信号来说,通常都有一个单线程管理器的好习惯:这个线程应该在库中或可以在应用程序中启动它?

谢谢大家。

回答

-1

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

+0

信号量在应用程序之间共享。 – MirkoBanchi

+0

如何?你使用某种类型的进程间通信方案吗? – insomniac2846

+0

POSIX信号量可通过例如'/ dev/shm'进行访问,因此在进程间共享。 – MirkoBanchi

0

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

还有一场小规模的比赛,因为锁定的过程可能会在锁定之后但在写入其pid之前死亡。 AFAIK无法避免使用信号量。 (如果你有一个锁定实现,其中pid是以自动方式写入锁定变量,但你可能需要自己写这个。)