Linux系统编程--信号与管道

ops/2025/2/12 3:52:37/

1、信号与管道是什么?

首先了解信号与管道的意义,我们需要了解Linux系统中进程之间是如何通信的。Linux操作系统下,以进程为单位来分配或者管理资源,进程之间不能直接访问资源,因此,要求进程间的资源和信息共享就意味着进程之间能够相互通信。这就是通信机制:信号、管道。

2、进程通信的目的?

数据传输、共享数据、通知事件、资源共享、进程控制

3、何为通信机制?

了解该机制需要明白进程是如何来互相通信的,Linux支持多种进程间的通信,IPC机制,包括共享内存、消息队列、信号量、网络通信。

好了,介绍完这些需要了解的知识后进入正题!

一、信号

信号是一种异步的通知机制,用于在软件层面模拟中断机制。当一个进程收到信号时,其行为类似于处理器接收到一个中断请求,信号属于一种软中断方式

操作:

1.查看信号:kill -l

不可靠信号:1-31

可靠信号:34-64

9 号(SIGKILL),19 号(SIGSTOP) 不允许被忽略,也不允许被改造

杀死进程:Ctrl + C [ (2)、SIGINT ]

                  Ctrl + \  [ (3)、SIGQUIT ]

                KILL [ (9)、SIGKILL ]  kill-sig pid   sig信号

内核:当我们的程序出现一些错误的时候,例如段错误等,内核会给我们的进程发送杀死当前进程的信号。

程序:通过函数发送信号:kill

2、给进程发送信号:kill
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
形参:
        pid -- 你要给哪一个进程发送信号
        sig -- 信号(可以写编号,也可以写后面的宏定义)
返回值:
成功返回 0,失败返回-1
特殊信号:
        9 -- SIGKILL -- 杀死进程,不可以被忽略或者改造;
        14 -- SIGALRM -- 闹钟信号,杀死进程
        17 -- SIGCHLD -- 只要子进程状态发生改变,父进程就能接收到该信号
        18 -- SIGCONT -- 恢复 19 号 信号 暂停 的进程
        19 -- SIGSTOP -- 暂停进程
3、给自己发送信号:raise
#include <signal.h>
int raise(int sig);
形参:
sig -- 信号
等价于:
kill(getpid(),sig);
4、计时杀死进程:alarm
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
形参:
seconds 秒数
功能:
设置闹钟,闹钟事件到,产生闹钟信号,闹钟信号默认杀死当前进程;
如果在该 alarm 之前,已经设置过闹钟,此时闹钟会给更新
返回值:
如果上一次设置的有闹钟,返回上一个闹钟的剩余时间,否则返回 0;
5、产生信号再接触阻塞状态:pause
#include <unistd.h>
int pause(void);
只要运行,就阻塞,直到有一个信号产生,才会解除阻塞
6、信号处理函数:signal
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
形参:
signum -- 要处理的信号
handler -- SIG_DFL -- 默认处理
-- SIG_IGN -- 忽略处理
-- 函数 指针 -- 捕获到该信号,执行函数指针对应的函数
具体用法:
signal(2,SIG_DFL); 默认处理
signal(2,SIG_IGN); 忽略处理
signel(信号,Fun);
捕获到信号,执行 Fun 函数
7、注册退出清理函数:atexit
#include <stdlib.h>
int atexit(void (*function)(void));
//形参:函数指针
void Clean(void)
{
printf(“%s 被运行\n”,__FUNCTION__);
}
int main()
{
atexit(Clean);//注册退出清理函数,在 main 函数退出的时候,直到自动运行 Clean 函数
}

二、管道

管道(Pipe)是一种常见的进程间通信(IPC)机制,它允许两个进程通过一个半双工的通道进行数据传输。它作为两个进程之间的数据传输媒介。管道的一端连接一个写进程,另一端连接一个读进程

创建和使用

  • 创建匿名管道通常使用pipe()系统调用。
  • 使用fork()创建子进程后,父进程写入管道,子进程从管道中读取数据。
  • 写入管道通常使用write()系统调用,而读取管道通常使用read()系统调用。

管道的特点:

属于半双工通信
管道正常的情况下,管道中没有内容, read 会阻塞;写端关闭
管道文件和普通的文件的区别:
管道的内容,一旦读走,就没有了
管道文件不允许使用 lseek 等光标偏移的函数
管道一定遵循先进先出的原则
管道有大小:
64k   64 * 1024 = 65536 字节
1、无名管道
适用于父子进程之间的通信;
没有名字的管道,没有 真正的介质文件存在 仅仅以 文件描述符 的形式可以让我们操作
创建:pipe
#include <unistd.h>
int pipe(int pipefd[2]);
形参:
pipefd -- 整型数组,2 个元素
pipe fd[0] :存放的管道的 读端 的文件描述符
pipe fd[1] :存放的管道的 写端 的文件描述符
返回值:
成功返回 0,失败返回-1;
用法:
int fd[2] = {0};
pipe(fd);  fd[0]  fd[1]
创建子进程,也得有管道
问题:先创建子进程还是先创建管道?
先创建管道,子进程复制父进程资源(包含管道),

2、有名管道(记忆)

适用于任意两个进程

1. 创建管道文件 .fifo
2. 打开管道文件 open
3. 读写 write read
4. 关闭 close
3、创建管道文件:mkfifo
#include <sys/stat.h>
#include<sys/types.h>
int mkfifo(const char * pathname,mode_t mode)
参数
pathname:要创建的 FIFO 文件的名字(路径+名字 以.fifo 结尾)
mode: 创建的 FIFO 文件的权限
真正的权限:mode &(~umask)
返回值
成功返回 0,失败(如果管道文件原本存在,直接返回失败)返回-1。
4、打开管道文件:open
int fd = open(char *pathname,int flag);
flag 只能在 O_RDONLY 和 O_WRONLY 中选择其一;
open 函数在打开管道文件的时候,必须两方都执行 open,open 才能打开,只有一个进程执行 open,open 会发生阻塞,直到另外的一个进程也运行到 open 的位置,两方同时解除阻塞
5、有名管道的删除:unlink
int unlink(const char * pathname)
#include <unistd.h>
参数
pathname:要删除的 FIFO 文件的名字(带路径)
返回值:
成功返回 0,失败返回-1。


http://www.ppmy.cn/ops/29229.html

相关文章

初识Vue-组件化开发(详解各个组件)

目录 一、组件介绍 1.概念 2.特点 3.作用 4.应用 5.分类 二、组件语法 1.定义挂载vue应用 2.注册全局组件 实例 1.自定义组件 2.计数器 3.组件的复用 4.局部组件 实例 5.Prop 6.动态Prop 7.Prop 验证 三、创建组件的关键概念和语法 1. 组件定义 2. 组件选…

在Vue中使用v-viewer插件实现点击图片预览

v-viewer是一款基于 viewer.js 封装的Vue版插件&#xff0c;可用于图像查看&#xff0c;以及图片的旋转、缩放等功能预览。 使用步骤&#xff1a; 第一步&#xff1a;安装插件 yarn add v-viewernext viewerjs 第二步&#xff1a;引入v-viewer及必需的css样式&#xff0c;并…

SpringBoot日志管理

一.Logback SpringBoot默认使用Logback组件作为日志管理。 Logback是log4j创始人设计的一个开源日志组件。在SpringBoot中已经整合了Logback的依赖&#xff0c;所以我们不需要额外的添加其他依赖,这些日志格式在我们开发过程中是不需要开发人员自己写的&#xff0c;直接cv拿过来…

全志ARM-修改开发板内核启动日志

修改开发板内核日志输出级别&#xff1a; 默认输出级别为1&#xff0c;需要用超级用户权限修改 sudo vi /boot/orangepiEvn.txt 把第一行内核启动输出权限改为7&#xff0c;第二行把输出方式该为“serial”串口输出

WPS文字页面横向

要将WPS文字页面设置为横向&#xff0c;可以按照以下步骤操作&#xff1a;12 打开WPS文字文档&#xff0c;点击“页面布局”选项卡。在“页面布局”中找到“纸张方向”选项。选择“横向”&#xff0c;这样整篇文档的页面方向就会变为横向。 如果只需要将文档中的特定页面设置…

《微服务设计》读书笔记

此为阅读纽曼《微服务设计》一书后总结的读书笔记&#xff0c;点此处下载PDF文档。 一、微服务的概念 微服务&#xff08;或称微服务架构&#xff09;是一种云原生架构方法&#xff0c;其核心思想在于将单个应用拆分为众多 小型、松散耦合的服务&#xff0c;服务之间均通过网…

智能家居|基于SprinBoot+vue的智能家居系统(源码+数据库+文档)

智能家居目录 基于SprinBootvue的智能家居系统 一、前言 二、系统设计 三、系统功能设计 1管理员&#xff1a;个人中心管理功能的详细实现 2管理员&#xff1a;用户信息管理功能的详细实现 3管理员&#xff1a;家具管理功能的详细实现 4管理员&#xff1a;任务管理功能…

AIX7环境上一次艰难的Oracle打补丁经历

系统环境 AIX &#xff1a;7200-05-03-2148 Oracle&#xff1a;11.2.0.4 PSU: 11.2.0.4.201020&#xff08;31718723&#xff09; perl:5.28 问题一&#xff1a;AUTO patch #/u01/app/11.2.0/grid/OPatch/opatch auto /tmp/31718723 错误信息如下&#xff1a;匹配mos 2516761.1…