kill系统调用及示例

kill – 发送信号给进程

函数介绍

kill系统调用用于向指定的进程发送信号。信号是Linux系统中进程间通信的一种方式,用于通知进程发生了某种事件。通过kill可以控制其他进程的行为,如终止、暂停、继续等。

函数原型

#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int sig);

功能

向指定进程发送信号,用于进程控制和通信。

参数

  • pid_t pid: 目标进程ID
    • > 0: 发送给指定进程ID
    • = 0: 发送给当前进程组的所有进程
    • -1: 发送给有权限发送的所有进程(除init)
    • < -1: 发送给进程组ID为-pid的所有进程
  • int sig: 要发送的信号编号
    • 0: 空信号,用于检查进程是否存在
    • SIGTERM(15): 终止信号(默认)
    • SIGKILL(9): 强制终止信号
    • SIGSTOP(17): 暂停信号
    • SIGCONT(19): 继续信号

返回值

  • 成功时返回0
  • 失败时返回-1,并设置errno:
    • EINVAL: 信号编号无效
    • EPERM: 权限不足
    • ESRCH: 进程不存在

相似函数

  • raise(): 向当前进程发送信号
  • killpg(): 向进程组发送信号
  • signal(): 设置信号处理函数
  • sigaction(): 更高级的信号处理函数

示例代码

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include <string.h>

int main() {
    pid_t current_pid = getpid();
    pid_t parent_pid = getppid();
    
    printf("=== Kill函数示例 ===\n");
    printf("当前进程PID: %d\n", current_pid);
    printf("父进程PID: %d\n", parent_pid);
    
    // 示例1: 发送空信号检查进程是否存在
    printf("\n示例1: 检查进程是否存在\n");
    if (kill(current_pid, 0) == 0) {
        printf("  进程 %d 存在\n", current_pid);
    } else {
        printf("  进程 %d 不存在\n", current_pid);
    }
    
    // 示例2: 向自己发送SIGTERM信号
    printf("\n示例2: 向自己发送SIGTERM信号\n");
    printf("  发送SIGTERM信号前...\n");
    
    // 创建子进程来演示,避免终止主进程
    pid_t child_pid = fork();
    if (child_pid == 0) {
        // 子进程
        printf("  子进程 %d 准备接收信号\n", getpid());
        sleep(1);
        printf("  子进程退出\n");
        exit(0);
    } else if (child_pid > 0) {
        // 父进程
        sleep(1); // 等待子进程准备就绪
        printf("  向子进程 %d 发送SIGTERM信号\n", child_pid);
        if (kill(child_pid, SIGTERM) == 0) {
            printf("  信号发送成功\n");
        } else {
            perror("  kill失败");
        }
        wait(NULL); // 等待子进程结束
    }
    
    // 示例3: 演示不同信号的效果
    printf("\n示例3: 不同信号的效果\n");
    
    // 创建用于演示的子进程
    child_pid = fork();
    if (child_pid == 0) {
        // 子进程循环运行
        printf("  子进程 %d 开始运行...\n", getpid());
        int i = 0;
        while (i < 10) {
            printf("  子进程运行中... %d\n", i++);
            sleep(1);
        }
        printf("  子进程正常退出\n");
        exit(0);
    } else if (child_pid > 0) {
        // 父进程
        sleep(2); // 让子进程运行一会儿
        
        printf("  向子进程 %d 发送SIGSTOP信号(暂停)\n", child_pid);
        kill(child_pid, SIGSTOP);
        sleep(2);
        
        printf("  向子进程 %d 发送SIGCONT信号(继续)\n", child_pid);
        kill(child_pid, SIGCONT);
        sleep(2);
        
        printf("  向子进程 %d 发送SIGTERM信号(终止)\n", child_pid);
        kill(child_pid, SIGTERM);
        wait(NULL);
    }
    
    // 示例4: 错误处理
    printf("\n示例4: 错误处理\n");
    if (kill(999999, SIGTERM) == -1) {
        printf("  向不存在的进程发送信号: %s\n", strerror(errno));
    }
    
    if (kill(parent_pid, 999) == -1) {
        printf("  发送无效信号: %s\n", strerror(errno));
    }
    
    printf("\n程序执行完毕\n");
    return 0;
}

(https://www.calcguide.tech/2025/08/16/kill%e7%b3%bb%e7%bb%9f%e8%b0%83%e7%94%a8%e5%8f%8a%e7%a4%ba%e4%be%8b/)

此条目发表在linux文章分类目录。将固定链接加入收藏夹。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注