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

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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/589833.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(树莓派4b与消息分发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 和多线程相比较&#xff0c;多进程最大的好处就是安全。一个进程挂了&#xff0c;不影响其他进程的运行。但是多线程也有自己的优点&#xff0c;那…

Ex1-C6油气化工防爆轮式巡检机器人

Ex1系列防爆轮式巡检机器人整机采用防爆设计&#xff0c;防爆等级为Exd II CT4 Gb。机器人通过无轨3D形态导航技术&#xff0c;结合360度防爆云台和无线防爆充电桩&#xff0c;实现整套防爆标准&#xff0c;可广泛应用于石油、燃气、化工、冶金等II类爆炸环境中&#xff0c;代替…

程序员缓解工作压力——方法分享

前言 作为一名初级程序员&#xff0c;我承认自己在应对工作压力方面还有待提高。在日常工作中&#xff0c;我时常感到压力山大&#xff0c;尤其是在面对复杂问题或紧迫的项目期限时。然而&#xff0c;为了保持高效和持久的工作热情&#xff0c;我还是积极寻求并使用了一…

Python 贪吃蛇

文章目录 效果图&#xff1a;项目目录结构main.pygame/apple.pygame/base.pygame/snake.pyconstant.py 效果图&#xff1a; 项目目录结构 main.py from snake.game.apple import Apple # 导入苹果类 from snake.game.base import * # 导入游戏基类 from snake.game.snake im…

Linux之命令行参数与环境变量

命令行参数&环境变量 命令行参数 main函数也是一个函数&#xff0c;其实也可以携带参数的 int main( int argc, char *argv[ ], char *envp[ ] ) {program-statements } 那这里是有三个参数的: 第一个参数&#xff1a; argc 是个整型变量&#xff0c;表示命令行参数的个数…

WIFI/BT中蓝牙的硬件资源是如何调度的 UART和PCM接口传输的是什么信号

安卓或IOS手机中&#xff0c;wifi/bt中的蓝牙是如何调度硬件资源的&#xff0c;尤其是UART和PCM是如何分配的。M.2 wifi/bt模块或其他形式的模块中&#xff0c;蓝牙是如何调度硬件资源的&#xff0c;尤其是UART和PCM是如何分配的。今天我们就图文并茂的解决这个问题。 蓝牙文件…

SQL 基础 | AS 的用法介绍

SQL&#xff08;Structured Query Language&#xff09;是一种用于管理和操作数据库的标准编程语言。 在SQL中&#xff0c;AS关键字有几种不同的用法&#xff0c;主要用于重命名表、列或者查询结果。 以下是AS的一些常见用法&#xff1a; 重命名列&#xff1a;在SELECT语句中&a…

Vue生命周期都有哪些?

定义 Vue的生命周期就是实例从创建到销毁的一个过程&#xff0c;即从创建、初始化数据、编译模板、挂载Dom($el)->渲染、更新->渲染&#xff0c;卸载等一系列的过程。el是挂载点如<div id"app"></div>。 Vue的生命周期分为八个阶段 1.beforeCreate…

重看Spring聚焦BeanDefinition分析和构造

目录 一、对BeanDefinition的理解 &#xff08;一&#xff09;理解元信息 &#xff08;二&#xff09;BeanDefinition理解分析 二、BeanDefinition的结构设计分析 &#xff08;一&#xff09;整体结构体会 &#xff08;二&#xff09;重要接口和类分析 三、构造 BeanDef…

保姆级IDEA安装与配置教程(含视频+资料)

课程简介 本套课程主要针对 Java 基础开发相关的工具安装和使用&#xff0c;主要包含有 IDEA 的下载、安装、配置、使用、快捷键的使用等。 本套视频是作为新手最为实用的课程&#xff0c;IDEA 是 Java 企业级开发最为常用的继承开发环境。如果熟练使用 IDEA 的话&#xff0c…

【中断】【ARM64】学习总结

optee中的异常向量表解读–中断处理解读 https://mp.weixin.qq.com/s/gBsy4YDYTHGRsy2zcVr6Vg

c# winform快速建websocket服务器源码 wpf快速搭建websocket服务 c#简单建立websocket服务 websocket快速搭建

完整源码下载----->点击 随着互联网技术的飞速发展&#xff0c;实时交互和数据推送已成为众多应用的核心需求。传统的HTTP协议&#xff0c;基于请求-响应模型&#xff0c;无法满足现代Web应用对低延迟、双向通信的高标准要求。在此背景下&#xff0c;WebSocket协议应运而生…

Polardb集中式部署体验

前言说明 PolarDB是阿⾥云数据库团队⾃主开发的云原⽣数据库。据了解PolarDB是产品品牌统称&#xff0c;云上PolarDB提供了Polardb MySQL版&#xff08;集中式数据库&#xff09;&#xff0c;PolarDB PostgreSQL版&#xff08;集中式数据库&#xff09;和PolarDB分布式版&…

人工智能论文:BERT和GPT, GPT-2, GPT-3 的简明对比和主要区别

在BERT的论文里面&#xff1a; 2018.10 BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding&#xff0c;BERT已经解释了BERT&#xff0c;GPT&#xff0c;ELMo的区别。 *ELMo为双向RNN&#xff0c;请忽略。 主要区别&#xff1a; BERT使用的是…

机器学习:深入解析SVM的核心概念【四、软间隔与正则化】

软间隔与正则化 问题一&#xff1a;优化目标函数是如何得到的&#xff1f;得到的过程是怎样的&#xff1f;问题二&#xff1a;拉格朗日乘子法计算详细过程问题三&#xff1a;KKT条件求解过程问题四&#xff1a;结构风险最小化&#xff08;SRM&#xff09;的原理 在前面的讨论中…

批量视频剪辑新选择:一键式按照指定秒数分割视频并轻松提取视频中的音频,让视频处理更高效!

是否经常为大量的视频剪辑工作感到头疼&#xff1f;还在一个个手动分割、提取音频吗&#xff1f;现在&#xff0c;我们为你带来了一款全新的视频批量剪辑神器&#xff0c;让你轻松应对各种视频处理需求&#xff01; 首先&#xff0c;进入媒体梦工厂的主页面&#xff0c;并在板…

机器学习之基于Tensorflow(LSTM)进行多变量时间序列预测股价

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 项目简介&#xff1a;机器学习之基于TensorFlow&#xff08;LSTM&#xff09;进行多变量时间序列预测股价 一、项目…

【Java从入门到精通】Java 正则表达式

目录 正则表达式实例 &#x1f349;java.util.regex 包 &#x1f349;实例 &#x1f349;捕获组 &#x1f349;实例 &#x1f349;RegexMatches.java 文件代码&#xff1a; &#x1f349;正则表达式语法 &#x1f349;Matcher 类的方法 &#x1f349;索引方法 &#…

【Qt QML】QLibrary加载共享库中的类

QLibrary是一个用于加载动态链接库&#xff08;或称为共享库&#xff09;的类。它提供了一种独立于平台的方式来访问库中的功能。 在QLibrary中&#xff0c;可以通过构造函数或setFileName()方法设置要加载的库文件名。当加载库文件时&#xff0c;QLibrary会搜索所有平台特定的…

消失的VCC和VEE,取而代之的VDD和VSS

一直以来&#xff0c;这些电源电压&#xff08;Vdd 和 Vss&#xff09;或&#xff08;Vcc 和 Vee&#xff09;的命名都有点耐人寻味&#xff0c;甚至令人困惑。但为什么呢&#xff1f; It has always been a bit intriguing and even confusing the nomenclature of these powe…