Linux系统编程(六)高级IO
目录
1. 阻塞和非阻塞 IO
2. IO 多路转接(select、poll、epoll)
3. 存储映射 IO(mmap)
4. 文件锁(fcntl、lockf、flock)
5. 管道实例 - 池类算法
1. 阻塞和非阻塞 IO
- 阻塞 IO:会等待操作的完成或期待事情的到来。会被信号打断(信号会打断阻塞中的系统调用),若被打断则错误码为 EINTR(假错)。操作的完成和期待事件的到来会通知阻塞的进程。
- 非阻塞 IO:若操作未完成或期待的事情还没到来,则立即返回,不会等待。若未发生期待事件则返回错误码 EAGAIN(假错)。不会通知,但可以通过轮询查看状态。
有限状态机编程例子,中继引擎实现,实现不同 tty 设备之间的中继引擎,实现 tty 之间相互通信,但是是忙等(因为没有使用阻塞 IO,没有用到同步手段):
1-io/advio/nonblock/relayer
2. IO 多路转接(select、poll、epoll)
上述有限状态机例子是 I/O 密集型任务,可以使用 IO 多路转接。
IO 多路转接:监视文件描述符的行为,当当前文件描述符发生了期待的行为的时候,才去执行后续的操作。可以监视多个文件描述符。
1. select() 可以用来监视多个文件描述符,包括可读、可写、异常文件描述符,移植性很好,比较古老,传参不稳定。以事件为单位来组织文件描述符。监视期间会阻塞,也会被信号打断(假错)。
#include <sys/select.h>int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);// 删除指定的fd
void FD_CLR(int fd, fd_set *set);
// 判断fd是否在集合中
int FD_ISSET(int fd, fd_set *set);
// 将fd加入到集合中
void FD_SET(int fd, fd_set *set);
// 清空集合
void FD_ZERO(fd_set *set);
缺点:
- 监视内容和监视结果存放在同一处 readfds、writefds、exceptfds。
- 文件描述符有大小限制。
2. poll() 可以等待在文件描述上发生的特定事件,以文件描述符为单位来组织事件。把期待的事件 events 和已经发生的事件 revents 区分开来了,可以移植。
#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);struct pollfd {int fd; /* file descriptor */short events; /* requested events */short revents; /* returned events */
};
如果将 timeout 设置为 0 即为非阻塞,-1 表示为阻塞。跳过 pollfd 结构体中的 events 来指定特定的期待事件。
3. epoll(),linux 基于 poll 来做的一些优化版本,不可移植。
#include <sys/epoll.h>// 打开一个epoll文件描述符
int epoll_create(int size);
int epoll_create1(int flags);// 控制epoll文件描述符
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);// 等待epoll文件描述符上的事件
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
int epoll_pwait(int epfd, struct epoll_event *events,int maxevents, int timeout,const sigset_t *sigmask);
3. 存储映射 IO(mmap)
可以使用 readv(2) 和 writev(2) 来将读写多个碎片 buffer。
#include <sys/uio.h>ssize_t readv(int fd, const struct iovec *iov, int iovcnt);ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
存储映射 IO 可以将某一块内存,或者某一个文件的内容映射到当前进程空间中。
1. mmap(2) 可以将文件或者设备映射到内存中,返回映射区域的起始地址。
#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
int munmap(void *addr, size_t length);
参数:
- addr: 指定映射的虚拟内存地址,若为 NULL 则由内核选择合适的虚拟内存地址;
- length:映射的长度;
- prot:映射内存的保护模式,可选值如下:
PROT_EXEC:可以被执行;
PROT_READ:可以被读取;
PROT_WRITE:可以被写入;
PROT_NONE:不可访问;
- flags:指定映射的类型,可选值如下:
MAP_FIXED:使用指定的起始虚拟内存地址进行映射;
MAP_SHARED:与其他所有映射到这个文件的进程共享映射空间(可实现共享内存);
MAP_PRIVATE:建立一个写时复制(copy-on-write)的私有映射空间;
MAP_ANONYMOUS:匿名映射,可以替代 malloc,不依赖于任何文件,并且当前空间被 初始化为 0;
.....
- fd:进行映射的文件描述符;
- offset:文件偏移量(从文件何处开始映射);
例子1,mmap.c,使用 mmap 打开文件,并且计算文件中 a 字符出现的次数:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc, char *argv[])
{if (argc < 2){fprintf(stderr, "Usage..\n");exit(1);}int fd;void *addr;char *p;struct stat statbuf;int anum = 0;if ((fd = open(argv[1], O_RDONLY)) < 0){perror("open");exit(1);}if (fstat(fd, &statbuf) < 0){perror("fstat");exit(1);}addr = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);if (addr == MAP_FAILED){perror("mmap()");exit(1);}p = (char *)addr;for (int i = 0; i < statbuf.st_size; i++){if (*(p + i) == 'a'){anum++;}}munmap(addr, statbuf.st_size);printf("the number of a in the file is: %d\n", anum);exit(0);
}
mmap 还能实现共享内存,从而实现有亲缘关系的进程间的通信。比如父进程先 mmap,然后再 fork,这样子进程也能访问父进程 mmap 出来的空间(flags 为 MAP_SHARED 和 MAP_ANONYMOUS)。
例子,share_mem.c,使用 mmap 实现父子进程间的共享内存(子进程写入 hello,父进程打印):
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>#define MEMSIZE 1024int main()
{int fd;pid_t pid;char *addr;addr = (char *)mmap(NULL, MEMSIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);if (addr == MAP_FAILED){perror("mmap");exit(1);}pid = fork();if (pid < 0){perror("fork");exit(1);}if (pid == 0) // child{strcpy(addr, "Hello!");munmap(addr, MEMSIZE);exit(0);}else // parent{wait(NULL);puts(addr);munmap(addr, MEMSIZE);exit(0);}
}
4. 文件锁(fcntl、lockf、flock)
对文件加锁是在 inode 结构体上进行的,如果对一个文件描述符进行了 dup 或者重新 open 了新的文件描述符,对不同的文件描述符加锁和解锁都是作用于同一个 inode 的。 有如下几种文件加锁方法:
fcntl() 前面讲过。Linux系统编程(二)文件IO/系统调用IO-CSDN博客
lockf() 可以对文件进行加锁或者解锁,在 linux 上 lockf 就是 fcntl 的封装。
#include <unistd.h>int lockf(int fd, int cmd, off_t len);

flock() 可以给打开的文件加上或移除咨询锁(advisory lock)。
#include <sys/file.h>int flock(int fd, int operation);
5. 管道实例 - 池类算法
例子:4-parallel/thread/mypipe。
Linux系统编程(李慧琴): Linux系统编程(李慧琴)学习代码及笔记
相关文章:
Linux系统编程(六)高级IO
目录 1. 阻塞和非阻塞 IO 2. IO 多路转接(select、poll、epoll) 3. 存储映射 IO(mmap) 4. 文件锁(fcntl、lockf、flock) 5. 管道实例 - 池类算法 1. 阻塞和非阻塞 IO 阻塞 IO:会等待操作的…...
Python与FPGA——全局二值化
文章目录 前言一、Python全局128二、Python全局均值三、Python全局OTSU四、FPGA全局128总结 前言 为什么要进行图像二值化,rgb图像有三个通道,处理图像的计算量较大,二值化的图像极大的减少了处理图像的计算量。即便从彩色图像转成了二值化图…...
《Docker极简教程》--Docker的高级特性--Docker Compose的使用
Docker Compose是一个用于定义和运行多容器Docker应用程序的工具。它允许开发人员通过简单的YAML文件来定义应用程序的服务、网络和卷等资源,并使用单个命令来启动、停止和管理整个应用程序的容器。以下是关于Docker Compose的一些关键信息和优势: 定义…...
tidyverse去除表格中含有NA的行
在tidyverse中,特别是使用dplyr包,去除含有NA的行可以通过filter()函数结合is.na()和any()或all()函数来实现。dplyr是tidyverse的一部分,提供了一系列用于数据操作的函数,使数据处理变得更加简单和直观。 以下是一个简单的例子&…...
开源爬虫技术在金融行业市场分析中的应用与实战解析
一、项目介绍 在当今信息技术飞速发展的时代,数据已成为企业最宝贵的资产之一。特别是在${industry}领域,海量数据的获取和分析对于企业洞察市场趋势、优化产品和服务至关重要。在这样的背景下,爬虫技术应运而生,它能够高效地从互…...
使用SMTP javamail发送邮件
一、SMTP协议 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。使用javamail编写发送…...
Hello C++ (c++是什么/c++怎么学/c++推荐书籍)
引言 其实C基础语法基本上已经学完,早就想开始写C的博客了,却因为其他各种事情一直没开始。原计划是想讲Linux系统虚拟机安装的,后来考虑了一下还是算了,等Linux学到一定程度再开始相关博客的写作和发表吧。今天写博客想给C开个头…...
最新的前端开发技术(2024年)
关于作者: 还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas࿰…...
GCN 翻译 - 2
2 FAST APROXIMATE CONVOLUTIONS ON GRAPHS 在这一章节,我们为这种特殊的的图基础的神经网络模型f(X, A)提供理论上的支持。我们考虑一个多层的图卷积网络(GCN),它通过以下方式进行层间的传播: 这里,是无…...
HBase 的安装与部署
目录 1 启动 zookeeper2 启动 Hadoop3 HBase 的安装与部署4 HBase 高可用 1 启动 zookeeper [huweihadoop101 ~]$ bin/zk_cluster.sh start2 启动 Hadoop [huweihadoop101 ~]$ bin/hdp_cluster.sh start3 HBase 的安装与部署 (1)将 hbase-2.0.5-bin.tar.…...
236.二叉搜索树的公共祖先
236.二叉树的公共祖先 思路 看到题想的是找到两个点的各自路径利用stack保存,根据路径长度大小将两个stack的值对齐到同一层,之后同时出栈节点,若相同则找到祖先节点。但是效率不高 看了大佬代码,递归思想很难理解。 根据大佬…...
【论文精读】大语言模型融合知识图谱的问答系统研究
💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢…...
LabVIEW高精度天线自动测试系统
LabVIEW高精度天线自动测试系统 系统是一个集成了LabVIEW软件的自动化天线测试平台,提高天线性能测试的精度与效率。系统通过远程控制测试仪表,实现了数据采集、方向图绘制、参数计算等功能,特别适用于对天线辐射特性的精确测量。 在天线的…...
7.3 支付模块 - 创建订单、查询订单、通知
支付模块 - 创建订单、查询订单、通知 文章目录 支付模块 - 创建订单、查询订单、通知一、生成支付二维码1.1 数据模型1.1.1 订单表1.1.2 订单明细表1.1.3 支付交易记录表 1.2 执行流程1.3 Dto1.3.1 AddOrderDto 商品订单1.3.2 PayRecordDto支付交易记录扩展字段1.3.3 雪花算法…...
灵魂指针,教给(一)
欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看,已成习惯 创作不易,多多支持! 一、内存和地址 1.1 内存 在介绍知识之前,先来想一个生活中的小栗子: 假如把你放在一个有100间屋子的酒店…...
Linux 开发工具 yum、git、gdb
目录 一、yum 1、软件包 2、rzsz 3、注意事项 4、查看软件包 5、安装软件 6、卸载软件 二、git操作 1、克隆三板斧 2、第一次使用会出现以下情况: 未配置用户名和邮箱: push后弹出提示 三、gdb使用 1、背景 2、使用方法 例一:…...
Markdown
这里写自定义目录标题 欢迎使用Markdown编辑器 新的改变 功能快捷键 合理的创建标题,有助于目录的生成 如何改变文本的样式 插入链接与图片 如何插入一段漂亮的代码片 生成一个适合你的列表 创建一个表格 设定内容居中、居左、居右 SmartyPants 创建一个自定义列表 …...
【Oracle】oracle中sql给表新增字段并添加注释说明;mysql新增、修改字段
oracle中sql给表新增字段并添加注释说明 ALTER TABLE 表名 ADD 字段名 类型 COMMENT ON COLUMN 表面.字段名 IS ‘注释内容’ ALTER TABLE GROUP ADD T NUMBER(18) COMMENT ON COLUMN GROUP.T IS ‘ID’ mysql新增、修改字段、已有字段增加默认值 ALTER TABLE 表名 ADD COL…...
【汇总】pytest简易教程
pytest作为python技术栈里面主流、火热的技术,非常有必要好好学一下,因为工作和面试都能用上; 它不仅简单易用,还很强大灵活,重点掌握fixture、parametrize参数化、allure-pytest插件等,这些在后续自动化框…...
openssl调试记录
openssl不能直接解密16进制密文,需要把密文转化成base64格式才能解密 调试记录如下:...
如何选择适合的单北斗变形监测一体机以提升基础设施安全?
本文将重点讨论如何选择适合的单北斗变形监测一体机,以增强基础设施的安全性。在当前基础设施建设快速发展的背景下,单北斗GNSS的应用显得尤为重要。通过深入理解单北斗变形监测的原理,用户能够更好地把握设备的核心优势,尤其是在…...
若依框架二次开发避坑指南:手把手教你定制菜品管理系统
若依框架二次开发实战:从零构建餐饮管理系统的高效避坑手册 当接到基于若依框架开发餐饮管理系统的任务时,很多开发者会陷入"能用但不好用"的困境。本文将分享我在三个不同规模餐饮项目中积累的实战经验,重点解析那些官方文档不会告…...
SDMatte企业级应用:批量商品图去背景+Alpha Matte交付方案
SDMatte企业级应用:批量商品图去背景Alpha Matte交付方案 1. 产品概述 SDMatte是一款专为商业场景设计的高精度AI抠图工具,特别适合电商、广告和设计行业的大规模图像处理需求。它能快速将商品图片中的主体与背景分离,生成带有Alpha通道的透…...
AutoUnipus:重新定义U校园学习效率的智能解决方案
AutoUnipus:重新定义U校园学习效率的智能解决方案 【免费下载链接】AutoUnipus U校园脚本,支持全自动答题,百分百正确 2024最新版 项目地址: https://gitcode.com/gh_mirrors/au/AutoUnipus 还在为U校园平台上堆积如山的网课任务而焦虑吗?每天花费…...
Qwen3.5-4B-Claude推理模型在算法面试辅导中的实战:分步推导+代码示例生成
Qwen3.5-4B-Claude推理模型在算法面试辅导中的实战:分步推导代码示例生成 1. 模型介绍与核心能力 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是一个专门针对推理任务优化的AI模型,它基于Qwen3.5-4B架构,通过蒸馏训练强化了结构化…...
别再只调库了!拆解一个智能家居语音项目,聊聊STM32裸机开发中多任务处理的几种实用思路
裸机开发的艺术:STM32智能家居项目中多任务处理的五种高阶策略 从智能家居项目看裸机开发的挑战与机遇 在嵌入式开发领域,RTOS(实时操作系统)的普及让许多开发者形成了思维定式——面对多任务需求时,第一反应往往是移植…...
Realistic Vision V5.1 创意工作流:利用GitHub管理提示词库与生成作品版本
Realistic Vision V5.1 创意工作流:利用GitHub管理提示词库与生成作品版本 你有没有遇到过这种情况?团队里每个人都在用Realistic Vision V5.1生成图片,但大家用的提示词五花八门,好的描述词散落在各个聊天记录里,生成…...
基于YOLOv8深度学习的驾驶员分心行为实时检测与语音预警系统【python源码+Pyqt5界面+数据集】
1. 项目背景与核心价值 开车时低头看手机、点烟、喝饮料这些看似平常的小动作,每年导致全球超过120万起交通事故。我去年参与某物流车队安全系统升级时,亲眼见过一个司机因为伸手拿水杯导致车辆偏离车道的事故录像——整个过程不到3秒。这正是我们开发这…...
2.4 微积分与自动微分1
微积分 导数与微分 操作之前记得检查版本确保 matplotlib 正确安装:在d2l环境下输入pip install matplotlib (windows版) 重启jupyter就可以运行了(如果还是不行自行移步ai) 1.我们通过简单的微分方式得到我们需要的极限 2.之后我们再试着…...
TuShare实战(二)高效构建多股数据面板
1. 为什么需要多股数据面板 做量化投资的朋友都知道,数据准备是最基础也最耗时的环节。想象一下,你正在研究一个投资策略,需要同时分析5只股票的历史走势。如果每次都要单独获取、整理每只股票的数据,那效率实在太低了。这就是为什…...
