• Linux应用开发进程间通信 视频课笔记


    【b站视频】Linux应用开发进程间通信
    2012年录制的视频了,应该有很多已经变动了。
    视频里讲的东西有用,但不完全有用,很适合我现在听。
    我现在正感冒,笔记肯定也挺散乱的,就简单记录而已。

    看Linux内核源码,不要太去纠结函数前面的输入正确性判断,主要看逻辑核心用了什么结构体,输入/输出了什么消息,做了什么操作。

    进程

    在这里插入图片描述

    进程就是正在跑的程序和正在管理它的内核信息。

    用./运行程序时,内核会将代码放入内存的代码区,然后cpu在逐行执行的过程中将数据望堆/栈分配。

    在这里插入图片描述
    23位系统,总共就4G的物理内存空间

    进程的状态

    在这里插入图片描述
    进程状态详解

    实时Linux系统就是可以在紧急状况下创建了进程之后不等内核来调度,非要立刻执行。

    进程的创建/销毁

    在这里插入图片描述
    因为每个进程都应当有自己的空间,但是分配下来又很费时,所以内核决定,等子进程需要读/写的时候,确切用到了数据内存的时候,才给分配空间并复制数据。——写时复制技术。
    在这里插入图片描述
    会打印8句printf

    在这里插入图片描述
    在这里插入图片描述
    进程管理5 ,12分40秒。

    在这里插入图片描述

    在代码里使用指令

    在这里插入图片描述
    在这里插入图片描述
    这句的效果就是
    /bin/ps $ ps -ef
    因为是可变参数,所以必须要以NULL结尾。

    在这里插入图片描述
    【用systerm()也可以执行命令,不知道有什么区别】

    system也是调用了exec函数去执行一个系统命令,可以把system函数理解成对exec函数的一个包装。可是,光光包装起来,加个返回值,有可能吗?比如说把return语句在exec后面,根据exec系列的函数的特性,return语句肯定不会执行,那system函数到底是怎么实现的呢?实际上,system函数的具体执行步骤是这样的:

    1.fork一个子进程;

    2.在子进程中调用exec函数去执行command;

    3.在父进程中调用wait去等待子进程结束。

    创建出一个子进程,然后在子进程中用exec来执行命令,即是子进程成功执行了没返回也没关系,还有父进程可以返回嘛!
    linux下execl和system函数

    exit()

    在这里插入图片描述
    printf里面的内容没有加\n ,内容会保存在缓冲区,并不会当场输出。
    用_exit(0)退出,不会清空缓冲区。
    用exit(0)退出,会清空缓冲区,在程序退出的时候把hello打印出来。

    wait()

    在这里插入图片描述
    让进程等着,可以选择接收信号 也可以NULL干等,可以指定等待某一个进程。

    在这里插入图片描述
    子进程睡5s退出之后主进程打印。
    LInux:进程等待之wait() & waitpid()


    守护进程

    在这里插入图片描述

    命名空间。在创建进程时防止起名重复。

    在这里插入图片描述

    写日志守护进程

    1. 创建一个进程并把它老爸干掉,从而过继到init这个稳定的继父手上
    2. 关掉从父进程那里继承来的文件描述符,摆脱所有负累。
    3. 改变目录
    4. 不知道干嘛用的
    5. 守护进程的职责:写日志输出。
      在这里插入图片描述

    守护进程的三种实现方式
    守护进程

    在这里插入图片描述
    在这里插入图片描述
    在内核的rc文件里加上这个守护进程的路径,就能开机自启动了。

    要关掉这个进程就用kill指令 $ sudo kill <进程号>


    进程间通信

    在这里插入图片描述
    通信,其实就是数据交互。交互,就是需要把数据放到一个对方能拿的地方,按一定的规则去拿。
    系统里可以放数据的地方有 内存、磁盘、网络缓冲区
    给管道创建并申请一个文件存储区域:申请内存空间 - 补充必要信息并创建inode - 将文件inode挂载进文件向量表 - 获得文件描述符 - 可以像文件一样使用write/read
    pipe[2]是同一块文件区域的两个文件描述符。还记得当初学文件描述符的时候说到多个进程可以打开同一个文件 并且有他们各自的读写进度。

    在这里插入图片描述
    无名管道用的是内核的内存空间,但是因为只有父子进程能拿到这个管道变量,所以只能用在父子进程里
    mkfifo()创建有名管道。它是像文件一样指定一个路径去开辟内存空间,这样的话 两个无关的进程就能通过路径来读取内容。但是这个路径下创建的文件本身不是用来保存已写未读数据的,它只是一个管道格式的空文件。就像纸杯电话这样?完美的比喻,而且纸杯电话也是半双工。

    信号

    在这里插入图片描述
    给进程发信号都是要打断进程做点操作,所以信号的实现原理就是软中断。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    【诶,父进程和子进程的进程号一样的吗?父进程想发signal杀死子进程要怎么搞】

    在这里插入图片描述
    这个alarm()默认是杀死进程的意思吗,只要设定是3秒,这个进程就会在3秒后直接退出,不会去打印下面的printf。

    信号处理

    1. 回调函数【由于每次只能发送一个信号,已经基本不怎么用了】
    2. 信号集合函数处理

    【Linux】信号的处理以及信号集操作函数
    进程间通信之信号集函数组

    共享内存

    在这里插入图片描述

    说是共享内存、消息队列、信号量都是这样开辟空间之后使用的。用$ ipcs 这个指令可以查看系统当前的这些信息
    在这里插入图片描述
    下面这些函数跟ioremap()的作用差不多,估计现在是被ioremap()给替代了。

    在这里插入图片描述
    写入共享内存
    在这里插入图片描述
    读出共享内存【就只改了第20行那边
    在这里插入图片描述

    0666是强制设定读写权限

    消息队列

    消息队列是能按顺序存放消息的一段空间,输入的信息会被监听,如果达到要求就可以取出信息。

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    消息队列里的消息并不一定是按顺序读取,也可以按照mtype把对应类型的信息挑选着读取出来。
    而且消息队列的存储方式是哈希表,当队列里有1w条消息时,要读取的时候是先找到某个区域,然后再在对应区域里挨个搜索的。
    在这里插入图片描述

    在这里插入图片描述
    下图增加了俩功能,【消息队列里没有消息可读的时候不死等 而是返回错误信息】【消息成功获取之后删除这个消息队列】
    在这里插入图片描述

    信号量

    啧,中华文化明明有这么丰富的描述词汇,为什么要把signal和semaphore叫做信号和信号量。就因为有+1-1这样的操作就觉得【量】字就可以了吗,就觉得加一个量字就足够了吗?***既然是跟锁放在一起用的,你起名也跟锁沾点边啊!【好了,大家回忆起这段话应该就能记住这俩的差别了】
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    使用Spring Initailizr功能~
    22年11月-外包-面试题
    Python爬虫零基础入门教程
    前端研习录(33)——命令行工具|ECMAScript6简介|Nodejs安装|Babel转码器安装及基本用法详解及示例分析
    二进制安装1.26版本k8s(docker)
    2022-2028全球有机硅醇酸面漆行业调研及趋势分析报告
    自然语言处理(八):预训练BERT
    从谷歌CRE谈起,运维如何培养服务意识?
    带你走过动态表单的那些坑
    Android修行手册 - TabLayout全解析(上)-常用方法
  • 原文地址:https://blog.csdn.net/qq_42635852/article/details/126003052