linux C 语言开发 (十) 进程间通讯--信号

发布于:2025-09-14 ⋅ 阅读:(23) ⋅ 点赞:(0)

    文章的目的为了记录使用C语言进行linux 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

  相关链接:

linux C 语言开发 (一) Window下用gcc编译和gdb调试

linux C 语言开发 (二) VsCode远程开发 linux

linux C 语言开发 (三) 建立云服务器

linux C 语言开发 (四) linux系统常用命令

linux C 语言开发 (五) linux系统目录结构

linux C 语言开发 (六) 程序的编辑和编译(vim、gcc)

linux C 语言开发 (七) 文件 IO 和标准 IO

linux C 语言开发 (八) 进程基础

linux C 语言开发 (九) 进程间通讯--管道

linux C 语言开发 (十) 进程间通讯--信号

Linux C到Android App开发推荐链接(入门十二章):

开源 java android app 开发(一)开发环境的搭建_csdn 开源 java android app-CSDN博客

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

linux C到.net mvc开发推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

内容:讲述进程的IPC通讯中信号的使用。

目录:

1.信号介绍

2.信号发送

3.信号接收

4.信号处理

一、信号介绍

信号是 Linux 系统响应某些条件而产生的一个事件, 接收到该信号的进程会执行相应的操作。
信号的产生有三种方式:
1)由硬件产生, 如从键盘输入 Ctrl+C 可以终止当前进程
2)由其他进程发送, 如可在 shell 进程下, 使用命令 kill -信号标号 PID, 向指定进程发送信号。
3)异常, 进程异常时会发送信号

信号演示:

二、信号发送

信号发送的函数:

函数 int kill(pid_t pid, int sig)
头文件 #include <sys/types.h> #include <signal.h>

函数 int kill(pid_t pid, int sig)
头文件 #include <sys/types.h> #include <signal.h>
参数 pid 大于 0, 时为向 PID 为 pid 的进程发送信号等于 0, 向同一个进程组的进程发送信号;等于-1, 除发送进程自身外, 向所有进程 ID 大于 1 的进程发送信号。小于-1, 向组 ID 等于该 pid 绝对值的进程组内所有进程发送信号。
参数 sig 设置发送的信号; 等于 0 时为空信号, 无信号发送。 常用来进行错误检查。
返回值 执行成功时, 返回值为 0; 错误时, 返回-1, 并设置相应的错误代码 errno
功能

用于向任何进程组或进程发送信号

函数 int raise(int sig)
头文件 #include <signal.h>
参数 sig 信号
功能 相当于 kill(getpid(),sig), 向进程自身发送信号

函数 unsigned int alarm(unsigned int seconds)
头文件 #include <unistd.h>
参数 设定的时间
功能 设定的时间超过后产生 SIGALARM 信号, 默认动作是终止进程。
注意 每个进程只能有一个 alarm()函数, 时间到后要想再次使用要重新注册

发送杀死信号keil.c杀死到test进程

kill.c代码

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
    pid_t pid;
    int sig;
    if(argc < 3){
        printf("Usage:%s <pid_t> <signal>\n",argv[0]);
        return -1;
    } 
    sig = atoi(argv[2]);
    pid = atoi(argv[1]);
    kill(pid,sig);
    return 0;
}

test.c代码

#include <stdio.h>
#include <unistd.h>
void main(void)
{
    while(1){
        sleep(1);
        printf("hello world\n");
    }
}

实验效果

三、信号接收

接收信号: 如果要让我们接收信号的进程可以接收到信号, 那么这个进程就不能停止。 让进程不停止
有三种方法:
 while
 sleep
 pause

sleep代码如下,其他的与这个类似

#include <stdio.h>
#include <unistd.h>
void main(void)
{
    while(1){
    sleep(1);
    printf("hello world\n");
    }
}

四、信号处理

信号是由操作系统来处理的, 说明信号的处理在内核态。 信号不一定会立即被处理, 此时会储存在信号的信号表中。

处理过程示意图:

函数 sighandler_t signal(int signum, sighandler_t handler);可以简化成 signal(参数 1, 参数 2);
头文件 #include <unistd.h>typedef void (*sighandler_t)(int);
参数 1 我们要进行处理的信号, 系统的信号我们可以在终端键入 kill -l 查看。
参数 2 处理的方式(是系统默认还是忽略还是捕获)忽略该信号, 填写“SIG_IGN” ;采用系统默认方式处理该信号, 填写“SIG_DFL” ;捕获到信号后执行此函数内容,定义格式为“typedef void (*sighandler_t)(int)” , sighandler_t 代表一个函数指针。
返回值 调用成功返回最后一次注册信号调用 signal()时的 handler 值; 失败返回 SIG_ERR。
功能 改变收到信号后的动作。

signal.c代码

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void myfun(int sig)
{
    if(sig == SIGINT){
    printf("get sigint\n");
    }
} 
int main(void)
{
    //signal(SIGINT,SIG_DFL);
    signal(SIGINT,myfun);
    while(1){
    sleep(1);
    printf("wait signal\n");
    } 
    return 0;
}

实验效果

编译运行后,打印wait signal,按下ctrl+c,打印 get signal。