如何在C语言中向进程发送信号?

18

我需要向一个进程发送信号,当进程接收到这个信号时会进行一些操作,在C语言中最好的实现方式是什么?

3个回答

27

发送信号给一个进程的方法是 kill(pid, signal); 然而,你应该意识到信号并不是一种健壮的进程间通信方式,除了父子进程之间的直接消息,因为其存在固有的竞争条件。管道、文件、目录、命名信号量、套接字、共享内存等都提供了更为出色的进程间通信方式。


哪个头文件定义了kill函数? - Koray Tugay
4
这在 <signal.h> 中声明。 - R.. GitHub STOP HELPING ICE
这是标准的C还是POSIX?我感到困惑,因为signal.h的维基百科页面不包括kill函数,而《C语言大全》也没有提到这个函数。 - Koray Tugay
1
纯C语言没有进程,因此无法向进程发送信号。在纯C中,您可以使用raise来向自己发送信号。进程和用于操作它们的函数来自POSIX。 - R.. GitHub STOP HELPING ICE
我想到一个主意,当我浏览网页并录制自己朗读时,向 Audacity 发送一个信号。 - Salem

4

如果您使用的是Unix系统之一,下列man页面将对您有所帮助:

man 2 kill
man 2 signal
man 2 sigvec

0

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
....

但是请注意,在处理信号时存在许多复杂性:

在Ubuntu 17.10中测试,GitHub upstream


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接