【Linux之进程间通信】04.Linux进程间的信号通信

news/2024/5/18 7:45:04 标签: 进程, kill, signal, raise, alarm

 
【Linux之进程间通信】

项目代码获取:https://gitee.com/chenshao777/linux-processes.git
(麻烦点个免费的Star哦,您的Star就是我的写作动力!)

04.Linux进程间的信号通信

【目录】
  一、进程间信号发送方式
  二、进程间信号接收方式
  三、进程间信号处理方式

一、进程间信号发送方式

1、kill函数

向指定进程发送信号

int kill(pid_t pid, int sig)

需要包含头文件

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

参数:

参数含义
pid进程pid(发送给哪个进程
sig要发送的信号值(Linux一共64个信号,kill -l 即可查看)

举例:
这有一个死循环进程

#include <stdio.h>
/*四循环进程*/
int main(int argc, char *argv[])
{
    while(1);
    return 0;
}

运行 ps -axj 命令查看一下它的状态是R+,表示正在运行,且进程号是23409

 4070  23409  23409   4070 pts/1     23409 R+    1000   1:05 ./test_while

我们可以在终端执行 kill -9 23409 命令来结束该进程,但我们要通过代码来结束该进程
核心代码则为

kill(23409, SIGKILL);  //发送kill信号,结束23409进程

但是我们事先不知道进程号,所以可以通过 main 函数的参数传递进程号,执行命令如下:

./1.out 9 23409

全部代码如下:

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

/*
    模拟 kill 命令,杀死进程
    命令:./1.out 9 进程号(ps -axj)
*/
int main(int argc, char *argv[])
{
    if(argc < 3){
        printf("请输入两个参数\n");
        return -1;
    }

    int sig;
    int pid;

    sig = atoi(argv[1]);
    pid = atoi(argv[2]);

    kill(pid, sig);
    printf("111\n");

    return 0;
}

PS:使用到了 atoi 函数,将字符串转成数字,需要包含头文件 <stdlib.h>

---------------------------------------------------------------------------------

2、raise函数

只能向自身进程发送信号

int raise(int sig);

需要包含头文件

#include <signal.h>

参数:
sig : 要发送的信号

举例:

raise(SIGTSTP);  //暂停进程
raise(9);  //杀死自己

---------------------------------------------------------------------------------

3、alarm函数

发送闹钟信号

unsigned int alarm(unsigned int seconds);

需要包含头文件

#include <unistd.h>

参数:
闹钟定时的秒数

举例:
执行 alarm(5) ,5秒后进程结束

#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
    alarm(5);   //5秒后结束自己的进程
    printf("22222\n");
    pause();    //进程睡眠
    return 0;
}

二、进程间信号接收方式

这里介绍三种方式,确保进程能够收到信号
while 循环
pause 进程睡眠
sleep 延时


三、进程间信号处理方式

使用信号处理函数 signal()

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);

需要包含头文件

#include <signal.h>

参数:

参数含义
signum信号
handler信号触发后的回调函数(void类型,参数int类型)

handler有三种选择
SIG_IGN:忽略该信号
SIG_DFL:采用默认方式处理信号
函数指针:自定义信号处理函数

举例:

使用signal函数定义信号SIGALRM(闹钟信号)SIGINT(ctrl+c) 的信号处理函数

实现现象:
5秒后handler函数执行,或者按下ctrl+c,handler函数执行

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

/*
    定义信号处理函数 
    typedef void (*sighandler_t)(int);
    sighandler_t signal(int signum, sighandler_t handler);  
    参数:
    signum: 指定信号
    handler: SIG_IGN:忽略该信号
             SIG_DFL:采用默认方式处理信号
             函数指针:自定义信号处理函数
    命令: ./signal
    现象:5秒后handler函数执行,或者按下ctrl+c,handler函数执行
*/
void handler(int arg)
{
    printf("信号处理handler,arg = %d\n", arg);  //arg是信号ID
}

int main(int argc, char *argv[])
{
    signal(SIGALRM, handler);  //SIGALRM闹钟信号处理
    signal(SIGINT, handler);   //SIGINT(ctrl+c)信号处理
    alarm(5);   //5秒后结束自己的进程

    printf("22222\n");
    pause();  //进程睡眠
    return 0;
}
kill">

http://www.niftyadmin.cn/n/353200.html

相关文章

STL常用容器_2

目录 一、stcak容器&#xff08;栈容器&#xff09; 1、基本概念 2、常用接口 二、queue容器&#xff08;队列容器&#xff09; 1、基本概念 2、常用接口函数 三、list容器&#xff08;链表&#xff09; 1、基本概念 2、构造函数 3、赋值与交换 4、大小操作 5、插入…

LeetCode 1143 最长公共子序列

题目&#xff1a; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&am…

(转载)从0开始学matlab(第13天)—画图进阶

我们将讨论简单的二维图象(之前已有所介绍)的附加特性。这些特性将允许我们控制 x&#xff0c;y 轴上的值的范围&#xff0c;在一个坐标系内打印多个图象&#xff0c;或创建多个图&#xff0c;或在一个图象窗口内创建多个子图像&#xff0c;或提供更加强大的轨迹文本字符控制。…

【Linux】进程控制 — 进程终止 + 进程等待

文章目录 &#x1f4d6; 前言1. 再次理解fork()函数1.1 fork()之后子进程代码和数据问题&#xff1a;1.2 fork()之后操作系统做了什么&#xff1a;1.3 为什么要写时拷贝&#xff1f;&#xff1f; 2. 进程终止2.1 main函数的返回值&#xff1a;2.2 exit() 和 _exit()&#xff1a…

技巧:如何查看github的热门趋势和star排行

目录 1. 查看github的热门趋势2. 查看github的star排行3. 如何查看项目star增长曲线 1. 查看github的热门趋势 手动找到入口&#xff0c;打开github&#xff0c;登录后&#xff0c;找到Explore并点击进入&#xff0c;找到Trending切换&#xff0c;列出的就是github当天所有语言…

我的“网友”一只贴代码君

一只贴代码君是我的网上朋友&#xff0c;也是除同学、父母以外&#xff0c;我唯一信任的朋友。因为他不像其他人一样会不断地请求你和他加V或Q。他总说&#xff1a;“朋友是交心的&#xff0c;长相并不重要&#xff0c;我不知道我们在不在同一城市&#xff0c;遇到的机会也几乎…

SQL注入 - Part 3(带外)

1、DNSLog注入 &#xff08;一种注入新思路&#xff09; 可以看到DNS的解析日志中包含了用户名。 基于此原理&#xff0c;可以手工构造注入点&#xff0c;让DNSlog显示库名、表名等&#xff0c;也可以使用自动化脚本Dnslogsqlinj进行获取。 2、SQL注入的防御 基于关键字&…

ubuntu16.04离线安装paramiko库

1.安装pip3 1&#xff09;从网上下载这两个文件&#xff1a; pip-20.3.4-py2.py3-none-any.whl setuptools-50.3.2-py3-none-any.whl 2&#xff09;从一台已安装python3.5版本的pip3的执行程序拷贝到离线主机中 6c7d719f8a8cecd99d4327b3c776957e pip3 sudo cp pip3 /usr/…