2012-07-02 55 views
3

我有一个用C语言编写的用于Linux平台的第三方应用程序。应用程序创建使用以下代码信号量:信号量在应用程序退出后保持打开状态

union semun { 
    int Value; 
    struct semid_ds *Buffer; 
    unsigned short * Array; 
} Arg; 

Arg.Value = 0; 

SemId = semget(IPC_PRIVATE , ONE_SEMAPHORE, 0666 | IPC_CREAT); 

semctl(SemId, 0, SETVAL, Arg); 

当应用程序退出时,这些信号量是通过使用下面的代码的应用程序中删除:

semctl(SemId, 0, IPC_RMID); 

如果应用程序异常停止(例如,通过发送多个SIGINT信号),这些信号量保持打开状态。这些信号量可以看出打开通过使用下面的命令:

ipcs -s 

这些信号量具有手动通过使用用ipcrm命令被从系统中除去。

如何确保在应用程序最终退出时应用程序创建的信号量会被删除?我读过exit()调用会关闭所有打开的已命名信号量。但是,这些并不被称为信号量。

我事先感谢您的帮助。

+1

这就是为什么我们有些人从来不喜欢System V信号和相关项目。 – bmargulies

回答

3

为了处理异常终止,我们可以安装信号处理程序

/* signal handlers available in signal.h */ 
#include <signal.h> 

void SignalHandler(int iSignalNum) 
{ 
    switch(iSignalNum) 
    { 
    case SIGINT: 
    case SIGSEGV: 
    case SIGTSTP: 
     { 
      /* Add Stuffs if necessary */ 
      semctl(SemId, 0, IPC_RMID); 
     } 
    break; 
    default: 
     break; 
    } 
    exit(0); 
}   


int main() 
{ 
     .... 

     /* Register the signal handlers */ 
     signal(SIGINT, SignalHandler); 
     signal(SIGSEGV, SignalHandler); 
     signal(SIGTSTP, SignalHandler); 
     ..... 
} 
3

您可能希望使用atexit()注册应用程序定义的退出处理程序。

void myexit(void) 
{ 
    semctl(SemId, 0, IPC_RMID); 
} 

... 

int main() 
{ 
    atexit(myexit); /* register exit handler */ 
    ... 

有关atexit()详见man atexit

+2

手册页特别指出:“如果一个进程由于信号的传递而异常终止,则不会调用使用atexit()(和on_exit(3))注册的函数”,所以这并不能真正解决他的问题。 – Duck

相关问题