当前位置: 首页 > news >正文

linux shell操作 - 05 进程 与 IO 模型

文章目录

  • 计算机内存分配
  • 进程与子进程
  • IO模型
  • 非阻塞IO
  • IO多路复用
  • 网络IO模型
    • 简单的socket
    • 并发的socket

计算机内存分配

一个32位,4G内存的计算机,内存使用分为两部分:

  • 操作系统内核空间
  • 应用程序的用户空间
  • 使用的操作系统不同,分配方式不同;
    在这里插入图片描述

进程与子进程

  • 进程是操作系统中资源管理的最小单位,它是将静态程序加载到内存中的一次动态的执行,包括进程创建、进程调度、进程销毁;

  • 每个进程有自己独有的内存(在用户空间内),进程的私有内存是相互独立的,且进程间无法直接通信;

  • 不同进程间通信,可以采用队列、管道、信号、共享内存(内核空间内)等方式;

  • 每个进程中可以创建一个或者多个线程,多个线程共享当前进程的部分内存资源,如代码、全局变量等;

  • 进程的内存分布
    在这里插入图片描述

  • 比如上图中的shell脚本,运行时,shell是父进程,python3开启子进程,父进程会等待子进程退出;当关闭shell进程(父进程)时,python3子进程由init进程接管。

  • 父进程中,当以fork()系统调用创建子进程时,子进程执行exit()系统调用退出后,内核中仍然存有子进程的信息,如pid, exit code, run time等,这些信息要等父进程通过wait/waitpid来回收,若一直未回收,则退出的子进程成为僵尸进程,一直占用系统资源。

  • 僵持进程无法通过kill关闭,随着数量增多,系统资源耗尽,导致系统瘫痪。

  • 可以进行IO(input输入、output输出)操作的内核对象
  • 如文件、管道、socket…
  • 流的入口是fd (file descriptor);

IO模型

  • 阻塞IO, 一直等待,不占用资源;无法同时处理多个任务;
    用户进程发起读的系统调用,当内核中socket fd未就绪时,一直阻塞等待;
    socket fd 就绪时,将内核中的socket数据拷贝到用户空间(拷贝期间阻塞等待);
    accept()阻塞
    在这里插入图片描述

  • 非阻塞IO, 忙轮询,占用CPU;
    应用程序不断轮询内核,对应的socket fd是否就绪,未就绪则返回(非阻塞);
    若已就绪,则拷贝内核中socket的数据到用户空间(阻塞)。
    accept()不阻塞
    在这里插入图片描述

  • IO多路复用,多个IO复用一个进程/线程,既可以阻塞等待不占用资源,又可以同时并发处理多个任务;

    • linux 支持select, poll, epoll
    • 应用程序通过系统调用让内核同时监控多个socket fd,一旦有网络事件发生,内核就遍历找到对应的socket,将其标记为可读,然后将所有的socket fd返回给应用程序;
    • 应用程序遍历所有的fd,找到就绪的fd,通过系统调用复制对应socket的数据到用户空间;
      在这里插入图片描述
  • 异步IO;

  • 应用程序发起异步read操作后,立即返回;

  • 内核中的fd就绪,复制数据完成,触发信号通知应用程序;

  • 全程无阻塞;
    在这里插入图片描述

  • 信号驱动IO

  • 首先注册信号处理函数;

  • 检查内核socket fd 是否就绪,未就绪直接返回;

  • 已就绪,则内核发送信号给应用程序,触发信号处理函数;

  • 信号处理函数,发起系统调用,从内核空间拷贝socket数据到用户空间(阻塞);
    在这里插入图片描述

 

非阻塞IO

  • 忙轮询,占用CPU;
  • 性能不如阻塞IO;
  • 代码流程,不停地 遍历所有的fd,查看是否就绪;
    在这里插入图片描述

 

IO多路复用

多个IO复用一个进程/线程,既可以阻塞等待不占用资源,又可以同时并发处理多个任务;

  • select

    • 最大连接数默认1024;
    • 两次拷贝,先将所有的fd 从用户空间拷贝到内核空间,由内核监控是否有fd就绪(可读或可写),也就是有网络事件发生;一旦有fd就绪,则遍历所有的fd集合,找到对应的fd并将其 标记为就绪态(可读、可写),然后将所有的fd(fd集合)从内核空间拷贝到用户空间,用户进程内遍历所有的fd,找出就绪的从进行读写;
    • 两次遍历
    • 并发量大时,性能指数式下降;
    • 代码流程:
      在这里插入图片描述
  • poll,与select 没有本质的区别,只是连接数比select多;

    • select 使用固定长度的 BitMap表示文件描述符集合,而poll 使用动态数组,以链表形式来组织,突破了 select 的文件描述符个数限制,还会受到系统文件描述符限制。
    • select/poll 都是使用线性结构存储进程的 socket 集合,都需要遍历文件描述符集合来找到可读或可写的 socket,时间复杂度为 O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合。
  • epoll,高性能的IO多路复用(仅linux支持)

    • 连接数更大,上限为进程的最大连接数;查看最大连接数cat /proc/sys/fs/file-max
    • 内核中采用红黑树结构,可高效地增删查(O(logn)),仅返回就绪的fd;
    • 将就绪的fd拷贝给用户进程,避免无用的遍历;
    • 适合并发量大的场景,可以解决C10K问题(单台服务器并发1w),
      在这里插入图片描述
    • 操作流程,使用epoll_create 创建内核epoll对象;epoll_ctl将要监控的socket加入红黑树,内核检测到有网络事件发生,则将对应的socket 连接放入一个就绪链表中,并复制给用户空间(epoll_wait返回);
      在这里插入图片描述
    • epoll支持水平触发边缘触发,边缘触发效率更高;select/poll仅仅支持水平触发,即内核socket缓冲区有数据就绪,在数据没有被进程读取完之前,会多次通知进程来读取;而边缘触发则仅仅通知一次,需要进程一次性读取所有的数据。例如,当快递放入快递站点时,管理员可能给你打多个电话催促你取快递,这种通知多次的方式就是水平触发;而当快递放入快递柜时,就只给你发送一次短信,仅仅通知一次,这种仅仅通知一次的方式就是边缘触发。
    • IO多路复用中有socket 就绪,并不一定可读、可写,此时为避免进程阻塞,需要结合非阻塞IO一起使用。

 

网络IO模型

  • 基于socket网络通信
    在这里插入图片描述
  • 客户端与服务端建立连接的过程
    • 客户端的socket对象调用connect((ip, port));
    • 服务器的网卡接收请求,并转发给OS ,实现TCP三次握手;同时在操作系统内核中维护两个队列,TCP半连接队列 & TCP全连接队列;半连接队列表示未完成三次握手,全连接队列表示完成三次握手,已完成socket连接;
    • 内核从TCP全连接队列取出当前socket连接,存储到内核文件列表中,同时将其fd返回用户空间,存入进程数组;
    • 应用程序中就可以拿着这个已连接的socket进行读写;
    • 读/写时 就对应阻塞IO、非阻塞IO、IO多路复用、异步IO、信号驱动的IO的情况;
      在这里插入图片描述

下面以python3语言为例演示socket的使用。

简单的socket

同时只能处理一个客户端的请求。

server:

import socket
import time
import sys
import signal  # 注册信号的处理函数def handler(signum: int, frame):"""接收到SIGINT信号时,打印一句话,并退出进程"""print("received signal:", signum)sys.exit(0)# 注册信号的处理函数
signal.signal(signal.SIGINT, handler)  # 使用 Ctrl + C 发送SIGINT信号# 网络层使用Ipv4
# 传输层使用TCP
sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 默认为阻塞的socket# 绑定ip
sock_server.bind(("localhost", 8000))
# 最多监听1000个连接
sock_server.listen(1000)  # 监听的socketwhile True:# TCP三次握手完成,接收socket连接conn, addr = sock_server.accept()  # accept阻塞 等待 socket连接就绪# 处理当前的socket连接,conn是已连接的socketprint("conn:", conn, addr)# 读 IO操作data = conn.recv(1024)  # 阻塞等待 内核中socket就绪,并拷贝数据到用户空间 print("received data:", data.decode())# 写 IO操作,拷贝到内核空间,写入socket缓冲区conn.send(b"hello, i am server. I have got your data.")# 在当前socket连接 的请求处理完之前,服务端不会接收下一个客户端的socket连接time.sleep(20)

client:

import socket
import time# 创建客户端
sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 建立连接
sock_client.connect(("localhost", 8000))# 发送数据
sock_client.send(b"hello, i am jack")
print("发送数据完成.")# 接收数据
data = sock_client.recv(1024) # 接收 1024 bytes    # 阻塞  内核fd未就绪->就绪  内核socket数据复制到用户空间
print("received data:", data.decode())

并发的socket

同时可以处理多个客户端的请求。

  • 阻塞+多进程
    • 随着请求数量的增多,子进程越来越多,(fork创建子进程复制父进程所有的资源)占用的系统资源越来越多,并发量大时会影响系统的性能,甚至导致系统崩溃;
    • 多进程上下文的切换包括用户空间、内核空间,消耗系统性能;
    • 所以并发量特别大时,多进程不是理想的方案。
# server.py
import socket
import os
import time
import sys
import signal  # 注册信号的处理函数
import multiprocessingdef handler(signum: int, frame):"""接收到SIGINT信号时,打印一句话,并退出进程"""print("received signal:", signum)sys.exit(0)# 注册信号的处理函数
signal.signal(signal.SIGINT, handler)  # 使用 Ctrl + C 发送SIGINT信号# 处理请求
def handle_request(conn, addr):print("subprocess:", os.getpid())print("conn:", conn, addr)flag = Falsewhile not flag:# 接收数据data = conn.recv(1024) # recv from kernelprint("received data:", data.decode())# 发送数据conn.send(b"I am server. I have got your data.")# 检测客户端的断开data = conn.recv(1024)print("客户端断开:", data.decode())if not data:conn.close()print("客户端已断开.")flag = Trueprint(f"{os.getpid()}子进程退出.")if __name__ == "__main__":# 网络层使用Ipv4# 传输层使用TCPsock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 默认为阻塞的socket# 绑定ipsock_server.bind(("localhost", 8000))# 最多监听1000个连接sock_server.listen(1000)  # 监听的socketwhile True:# TCP三次握手完成,接收socket连接conn, addr = sock_server.accept()  # accept阻塞 等待 socket连接就绪# 父进程 阻塞等待连接print("创建子进程.")# 子进程处理 请求sub_process = multiprocessing.Process(target=handle_request, args=(conn, addr))sub_process.daemon = Truesub_process.start()# client.py
import socket
import time# 创建客户端
sock_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 建立连接
sock_client.connect(("localhost", 8000))# 发送数据
sock_client.send(b"hello, i am jack")
print("发送数据完成.")# 接收数据
data = sock_client.recv(1024) # 接收 1024 bytes
print("received data:", data.decode())sock_client.close() # 客户端断开连接,会发送空数据到服务端
  • 阻塞+多线程
    • 线程是轻量级进程,同一个进程的多个线程可以共享当前进程的部分资源(代码、全局变量等),避免了过多的资源消耗;
    • 多线程的上下文切换,虽比多进程轻量,但大量的线程来回切换,也会给系统造成不小的开销;
    • 多线程需要考虑线程安全问题,另外每个线程也有自己的栈空间,也消耗内存;大量的线程必然会消耗大量的栈空间;
    • 所以对于特别大的并发量时,多线程也不是理想的方案。
在这里插入代码片
  • IO多路复用

相关文章:

linux shell操作 - 05 进程 与 IO 模型

文章目录 计算机内存分配进程与子进程流IO模型非阻塞IOIO多路复用网络IO模型简单的socket并发的socket 计算机内存分配 一个32位,4G内存的计算机,内存使用分为两部分: 操作系统内核空间;应用程序的用户空间使用的操作系统不同&a…...

让SOME/IP运转起来——SOME/IP系统设计(下)之数据库开发

上一篇我们介绍了SOME/IP矩阵的设计流程,这一篇重点介绍如何把SOME/IP矩阵顺利的交给下游软件团队进行开发。 车载以太网通信矩阵开发完成后,下一步应该做什么? 当我们完成SOME/IP矩阵开发,下一步需要把开发完成的矩阵换成固定格…...

Mybatis反射工厂类DefaultReflectorFactory

DefaultReflectorFactory是反射工厂接口ReflectorFactory的默认实现,其主要是实现了对反射对象Reflector的创建和缓存。 有三个方法: // 判断是否开启缓存boolean isClassCacheEnabled();// 设置是否缓存void setClassCacheEnabled(boolean classCacheEn…...

antDesignPro a-table样式二次封装

antDesignPro是跟element-ui类似的一个样式框架,其本身就是一个完整的后台系统,风格样式都很统一。我使用的是antd pro vue,版本是1.7.8。公司要求使用这个框架,但是UI又有自己的一套设计。这就导致我需要对部分组件进行一定的个性…...

找免费4K高清图片素材,就上这6个网站

使用图片素材怕侵权?那就上这6个网站,免费下载,4K高清无水印,赶紧收藏起来~ 1、菜鸟图库 https://www.sucai999.com/pic.html?vNTYxMjky 一个很大的素材库,站内主要还是以设计素材为主,像图片素材就有上百…...

代码随想录算法训练营第35天| 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

JAVA代码编写 860.柠檬水找零 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须…...

成为AI产品经理——TPR、FPR、ROC、AUC

目录 一、PR图、BEP 1.PR图 2.BEP 二、灵敏度、特异度 1.灵敏度 2.特异度 三、真正率、假正率 1.真正率 2.假正率 三、ROC、AUC 1.ROC 2.AUC 四、KS值 一、PR图、BEP 1.PR图 二分类问题模型通常输出的是一个概率值,我们需要设定一个阈值&#xff…...

java: Internal error in the mapping processor: java.lang.NullPointerException

启动java项目出错,其他人工程没有问题,别着急。 java: Internal error in the mapping processor: java.lang.NullPointerException at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifestUrl(DefaultVersionInformation.j…...

TCP知识点

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议,广泛应用于互联网。下面是TCP的一些知识点: TCP是一种可靠的协议,采用三次握手建立连接和四次挥手断开…...

大语言模型(LLMs)在 Amazon SageMaker 上的动手实践(一)

本期文章,我们将通过三个动手实验从浅到深地解读和演示大语言模型(LLMs),如何结合 Amazon SageMaker 的模型部署、模型编译优化、模型分布式训练等。 实验一:使用 Amazon SageMaker 构建基于开源 GPT-J 模型的对话机器…...

顶级数据恢复工具—— 最全的15个数据恢复软件榜单

在这个信息为王的数字时代,关键数据的丢失对个人和企业来说都可能是灾难性的。无论是由于意外删除、硬件故障还是恶意攻击,拥有强大的数据恢复解决方案都是至关重要的。在本综合指南中,我们将探索市场上最好的数据恢复软件,包括顶…...

【图像分类】【深度学习】【Pytorch版本】Inception-ResNet模型算法详解

【图像分类】【深度学习】【Pytorch版本】Inception-ResNet模型算法详解 文章目录 【图像分类】【深度学习】【Pytorch版本】Inception-ResNet模型算法详解前言Inception-ResNet讲解Inception-ResNet-V1Inception-ResNet-V2残差模块的缩放(Scaling of the Residuals)Inception-…...

Ubuntu 22.03 LTS 安装deepin-terminal 实现 终端 分屏

deepin-terminal 安装 源里面自带了这个软件,可以直接装 sudo apt install deepin-terminal 启动 按下Win键,输入deep即可快速检索出图标,点击启动 效果 分屏 CtrlShiftH 水平分割 CtrlShiftJ 垂直分割 最多分割成四个小窗口&#xff0…...

HTTP协议,Web框架回顾

HTTP 请求协议详情 -请求首行---》请求方式,请求地址,请求协议版本 -请求头---》key:value形式 -referer:上一次访问的地址 -user-agenet:客户端类型 -name:lqz -cookie&…...

el-checkbox 对勾颜色调整

对勾默认是白色 改的时候一直在试着改color人,其实不对。我用的是element ui 的复选框 /* 对勾颜色调整 */ .el-checkbox__inner::after{/* 是改这里的颜色 */border: 2px solid #1F7DFD; border-left: 0;border-top: 0;}...

系统管理精要:深度探索 Linux 监控与管理利器

前言 系统管理在 Linux 运维中扮演着至关重要的角色,涵盖了系统的配置、监控和维护。了解这些方面的工具和技术对于确保系统稳定运行至关重要。本文将着重介绍系统管理的关键部分,包括配置系统、监控系统状态和系统的日常维护,并以 top 和 vm…...

vue3之echarts渐变柱状图

vue3之echarts渐变柱状图 效果&#xff1a; 核心代码&#xff1a; <template><div class"abnormal"><div class"chart" ref"chartsRef"></div></div> </template><script setup> import * as echa…...

有一种浪漫,叫接触Linux

大家好&#xff0c;我是五月。 嵌入式开发 嵌入式开发产品必须依赖硬件和软件。 硬件一般使用51单片机&#xff0c;STM32、ARM&#xff0c;做成的产品以平板&#xff0c;手机&#xff0c;智能机器人&#xff0c;智能小车居多。 软件用的当然是以linux系统为蓝本&#xff0c…...

构建 App 的方法

目录 构建 App 使用 App 设计工具以交互方式构建 App 使用 MATLAB 函数以编程方式构建 App 构建实时编辑器任务 可以使用 MATLAB 来构建可以集成到各种环境中的交互式用户界面。可以构建两种类型的用户界面&#xff1a; App - 基于用户交互执行操作的自包含界面 实时编辑器…...

laravel实现发送邮件功能

Laravel提供了简单易用的邮件发送功能&#xff0c;使用SMTP、Mailgun、Sendmail等多种驱动程序&#xff0c;以及模板引擎将邮件内容进行渲染。 1.在项目目录.env配置email信息 MAIL_MAILERsmtp MAIL_HOSTsmtp.qq.com MAIL_PORT465 MAIL_FROM_ADDRESSuserqq.com MAIL_USERNAME…...

MogFace人脸检测效果实测:不同分辨率/压缩率/光照条件下的鲁棒性对比

MogFace人脸检测效果实测&#xff1a;不同分辨率/压缩率/光照条件下的鲁棒性对比 1. 引言 人脸检测是计算机视觉领域最基础也最核心的任务之一。无论是手机解锁、美颜相机&#xff0c;还是安防监控、智能门禁&#xff0c;背后都离不开一个稳定可靠的人脸检测模型。然而&#…...

ROS2 bag数据再利用:除了Rviz,如何用PCD点云文件做离线分析和算法测试?

ROS2 bag数据深度利用&#xff1a;解锁PCD点云文件的离线分析与算法测试新场景 当你在ROS2生态中积累了数百GB的传感器数据后&#xff0c;是否曾思考过这些.db3文件里封存的点云数据还能创造哪些超出实时可视化之外的价值&#xff1f;传统Rviz回放只是数据应用的起点&#xff0…...

Qwen3-VL-4B Pro多场景落地:盲人辅助APP中实时图像语音描述服务

Qwen3-VL-4B Pro多场景落地&#xff1a;盲人辅助APP中实时图像语音描述服务 1. 项目背景与意义 对于视力障碍人群来说&#xff0c;日常生活中最大的挑战之一就是无法获取视觉信息。传统的辅助手段如盲杖、导盲犬等虽然有用&#xff0c;但无法提供丰富的环境感知能力。随着人工…...

Informer时序模型实战:从数据预处理到预测结果可视化

1. Informer时序模型入门指南 时序预测是AI领域一个经典问题&#xff0c;从股票价格到电力负荷&#xff0c;从气象数据到设备传感器读数&#xff0c;都需要预测未来趋势。传统方法如ARIMA在处理长期依赖时表现不佳&#xff0c;而Informer模型通过改进Transformer架构&#xff0…...

外汇是什么?为什么我们离不开它?

外汇是什么?为什么我们离不开它? 一句话定义:外汇就是"外国的钱",但更准确地说,是以外币表示的、可以在国际上自由流通和结算的所有支付手段。它不仅包括美元、欧元、日元这些纸币和硬币,还包括外国银行存款、汇票、支票、债券等。 一、先搞懂:外汇到底是什…...

百度网盘分享链接解析技术:原理、实现与高效下载方案

百度网盘分享链接解析技术&#xff1a;原理、实现与高效下载方案 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 百度网盘作为国内主流的云存储服务&#xff0c;其分享功能为用…...

为RWKV7-1.5B-G1A开发VS Code插件:实现智能编程辅助

为RWKV7-1.5B-G1A开发VS Code插件&#xff1a;实现智能编程辅助 1. 引言&#xff1a;当AI助手遇见代码编辑器 想象一下这样的场景&#xff1a;你正在VS Code中编写Python代码&#xff0c;刚输入函数名&#xff0c;AI就自动补全了整个函数体&#xff1b;写注释描述需求后&…...

Janus-Pro-7B结合Vue前端框架:构建现代化AI管理平台

Janus-Pro-7B结合Vue前端框架&#xff1a;构建现代化AI管理平台 最近在折腾一个AI模型管理平台&#xff0c;后台用的是性能不错的Janus-Pro-7B&#xff0c;前端选来选去&#xff0c;还是决定用Vue。原因很简单&#xff0c;Vue的生态成熟&#xff0c;上手快&#xff0c;组件库丰…...

Qwen1.5-1.8B GPTQ模型解析:深入LSTM与Transformer在序列建模中的异同

Qwen1.5-1.8B GPTQ模型解析&#xff1a;深入LSTM与Transformer在序列建模中的异同 最近在和朋友聊起AI模型的发展时&#xff0c;他问了一个挺有意思的问题&#xff1a;“现在大家都在说Transformer&#xff0c;那以前很火的LSTM是不是就完全没用了&#xff1f;” 这个问题让我…...

梦幻动漫魔法工坊应用案例:为游戏角色设计动漫立绘

梦幻动漫魔法工坊应用案例&#xff1a;为游戏角色设计动漫立绘 1. 游戏角色设计的新选择 在游戏开发领域&#xff0c;角色立绘设计一直是既关键又耗时的环节。传统方式需要雇佣专业画师&#xff0c;从草图到上色往往需要数天时间&#xff0c;成本高昂且迭代困难。现在&#x…...