• 正文
  • 相关推荐
申请入驻 产业图谱

飞凌嵌入式ElfBoard-进程间的通信之信号的发送kill

16小时前
131
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

与shell中的 kill 命令相类似,一个进程可通过 kill()向另一个进程发送信号,之所以选择kill作为术语是因为早期的UNIX实现中大多数默认行为是终止进程;

1.头文件

#include <sys/types.h>

#include <signal.h>

2.函数原型

int kill(pid_t pid, int sig);

3.参数

pid:用于标识一个或者多个目标进程,pid有以下四种情况:

如果pid大于0,信号被发送到具有pid指定的ID的进程。

如果pid等于0,向与调用进程相同进程组中的所有进程发送信号。

如果pid等于-1,将信号发送到除进程1(init)外调用进程有权发送信号的每个进程。

如果pid小于-1,向进程组中ID为-pid的每个进程发送sig。

sig:指定要发送的信号,如果sig为0,则不发送信号,但仍然执行存在和权限检查,这可用于检查调用者所在的进程ID或进程组ID是否存在;

4.返回值

kill()函数会在失败时返回-1并设置errno变量。

还需要注意的是,在 Linux 系统中,如果一个进程想向另一个进程发送信号(例如 SIGKILL, SIGSTOP 等),必须满足一定的权限要求。发送信号的进程必须具备特定的权限;这些权限确保了进程不会随意向其他进程发送信号,避免不必要的干扰。一个进程可以通过特定的权限向其他进程发送信号;例如,Linux 中有一个叫做 CAP_KILL 的权限,它允许进程向其他进程发送信号。只有具有这种权限的进程才能发送信号。发送进程的真实或有效的用户ID必须等于目标进程的真实或保存的set-user-ID,即发送信号的进程的用户 ID 必须与目标进程的用户 ID 匹配,才能发送信号;这意味着,只有同一个用户下的进程才可以互相发送信号。对于 SIGCONT(继续执行信号)来说,规则稍微宽松一些;当发送信号的进程和接收信号的进程在同一会话(session)中时,即便没有严格的权限要求,也能发送 SIGCONT 信号;这是因为会话内的进程通常属于同一个用户组,允许彼此进行一定程度的通信。

5.示例:通过kill()函数进程间发送信号

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <signal.h>

#include <sys/wait.h>

int main() {

// 创建子进程

pid_t pid = fork();

if (pid < 0) {

perror("fork failed");

exit(EXIT_FAILURE);

} else if (pid == 0) {

// 子进程代码

printf("I am the child process. My PID is %d.\n", getpid());

// 模拟子进程一直运行

while (1) {

printf("Child process is running...\n");

sleep(1);

}

exit(EXIT_SUCCESS);

} else {

// 父进程代码

printf("I am the parent process. My PID is %d, and my child's PID is %d.\n", getpid(), pid);

// 让父进程等待几秒后终止子进程

sleep(5);

// 向子进程发送 SIGTERM 信号

printf("Sending SIGTERM to child process...\n");

if (kill(pid, SIGTERM) == -1) {

perror("Failed to send SIGTERM");

exit(EXIT_FAILURE);

}

// 等待子进程退出

wait(NULL);

printf("Child process has been terminated.\n");

}

return 0;

}

6.运行结果

I am the parent process. My PID is 8377, and my child's PID is 8378.

I am the child process. My PID is 8378.

Child process is running...

Child process is running...

Child process is running...

Child process is running...

Child process is running...

Sending SIGTERM to child process...

Child process has been terminated.

7.代码解析

使用 fork() 创建子进程。如果 fork() 返回 0,表示当前代码在子进程中执行,否则在父进程中执行。子进程打印自己的 PID,并进入一个无限循环,模拟持续运行。父进程等待 5 秒后,调用 kill(pid, SIGTERM) 向子进程发送 SIGTERM 信号,要求其终止。kill() 成功时返回 0,失败时返回 -1 并设置 errno。父进程调用 wait(NULL) 等待子进程结束,并打印消息确认子进程已终止。直接执行程序,等待5秒之后父进程会向子进程发送 SIGTERM 信号;进程会自动结束。

相关推荐