【问题标题】:Semaphores remain open after application exits应用程序退出后信号量保持打开状态
【发布时间】:2012-07-03 03:17:22
【问题描述】:

我有一个用 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() 调用关闭了所有打开的命名信号量。然而,这些不是命名的信号量。

提前感谢您的帮助。

【问题讨论】:

  • 这就是为什么我们中的一些人从不喜欢 System V 信号量和相关项目。

标签: c linux posix semaphore


【解决方案1】:

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

/* 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);
        .....
}

【讨论】:

    【解决方案2】:

    [This does not help in the case of an abnormal termination of the program]

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

    void myexit(void)
    {
      semctl(SemId, 0, IPC_RMID);
    }
    
    ...
    
    int main()
    {
      atexit(myexit); /* register exit handler */
      ...
    

    有关atexit()的详细信息,请参阅man atexit

    【讨论】:

    • 手册页明确指出“如果进程因传递信号而异常终止,则不会调用使用 atexit() 注册的函数(和 on_exit(3))”所以这并没有真正解决他的问题。
    猜你喜欢
    • 2018-05-13
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    相关资源
    最近更新 更多