信号安全使用sem_wait()/ sem_post()

Jer*_*emy 4 c posix

我试图在Linux上创建一个包装器,它控制一次允许多少次并发执行.为此,我使用系统范围的计数信号量.我创建信号量,执行a sem_wait(),启动子进程,然后在子进程sem_post()终止时执行.那样就好.

问题是如何安全地处理发送给这个包装器的信号.如果它没有捕获信号,则命令可能会在不执行a的情况下终止sem_post(),从而导致信号量计数永久减少1.所以,我创建了一个信号处理程序sem_post().但是,仍有一个问题.

如果在执行处理程序之前附加处理程序,则sem_wait()信号可能在sem_wait()完成之前到达,从而导致在sem_post()没有处理的情况下发生sem_wait().如果我sem_wait()在设置信号处理程序之前执行此操作,则可以反过来.

显而易见的下一步是在处理程序和设置过程中阻止信号sem_wait().这是我现在拥有的伪代码:

void handler(int sig)
{
  sem_post(sem);
  exit(1);
}

...
sigprocmask(...);   /* Block signals */
sigaction(...);     /* Set signal handler */
sem_wait(sem);
sigprocmask(...);   /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);
Run Code Online (Sandbox Code Playgroud)

现在的问题是sem_wait()可以阻塞,在此期间,信号被阻止.试图杀死进程的用户可能最终诉诸"kill -9",这是我不想鼓励的行为,因为无论如何我都无法处理这种情况.我可以使用sem_trywait()一小段时间并进行测试,sigpending()但这会影响公平性,因为不再保证等待信号量最长的进程将在下一次运行.

这里有一个真正安全的解决方案,允许我在信号量采集期间处理信号吗?我正在考虑求助于"我有信号量"全局并消除信号阻塞,但这不是100%安全,因为获取信号量并设置全局不是原子的,但可能比等待时阻塞信号更好.

Kek*_*koa 7

你确定sem_wait()导致信号被阻止吗?我不认为是这种情况.该用于手册页sem_wait()说,EINTR错误代码是从返回sem_wait()如果它是由一个信号中断.

您应该能够处理此错误代码,然后您的信号将被接收.您是否遇到未收到信号的情况?

我会确保你处理sem_wait()可以返回的错误代码.虽然可能很少见,但如果你想100%确定你想要100%的基数.