linux C 语言开发 (十) 进程间通讯--信号
文章的目的为了记录使用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。