我需要向一个进程发送信号,当进程接收到这个信号时会进行一些操作,在C语言中最好的实现方式是什么?
发送信号给一个进程的方法是 kill(pid, signal);
然而,你应该意识到信号并不是一种健壮的进程间通信方式,除了父子进程之间的直接消息,因为其存在固有的竞争条件。管道、文件、目录、命名信号量、套接字、共享内存等都提供了更为出色的进程间通信方式。
如果您使用的是Unix系统之一,下列man页面将对您有所帮助:
man 2 kill
man 2 signal
man 2 sigvec
kill
+ fork
可运行的 POSIX 示例
是时候来点有趣的了:
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <signal.h>
#include <stdbool.h> /* false */
#include <stdio.h> /* perror */
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
#include <sys/wait.h> /* wait, sleep */
#include <unistd.h> /* fork, write */
void signal_handler(int sig) {
char s1[] = "SIGUSR1\n";
char s2[] = "SIGUSR2\n";
if (sig == SIGUSR1) {
write(STDOUT_FILENO, s1, sizeof(s1));
} else if (sig == SIGUSR2) {
write(STDOUT_FILENO, s2, sizeof(s2));
}
signal(sig, signal_handler);
}
int main() {
pid_t pid;
signal(SIGUSR1, signal_handler);
signal(SIGUSR2, signal_handler);
pid = fork();
if (pid == -1) {
perror("fork");
assert(false);
} else {
if (pid == 0) {
while (1);
exit(EXIT_SUCCESS);
}
while (1) {
kill(pid, SIGUSR1);
sleep(1);
kill(pid, SIGUSR2);
sleep(1);
}
}
return EXIT_SUCCESS;
}
编译并运行:
gcc -std=c99 signal_fork.c
./a.out
结果:
SIGUSR1
SIGUSR2
SIGUSR1
SIGUSR2
....
但是请注意,在处理信号时存在许多复杂性:
man 7 signal
,SA_RESTART
sig_atomic_t
,则只能从信号处理程序中访问它们:sig_atomic_t实际上是如何工作的?在Ubuntu 17.10中测试,GitHub upstream。
<signal.h>
中声明。 - R.. GitHub STOP HELPING ICEraise
来向自己发送信号。进程和用于操作它们的函数来自POSIX。 - R.. GitHub STOP HELPING ICEAudacity
发送一个信号。 - Salem