
Linux编程一条龙服务
文章平均质量分 95
包含Linux操作、系统编程、网络编程等知识的专栏
利刃大大
不怕山高,只怕腿软
展开
-
【网络编程】十五、多路转接之 select
select 函数是一种用于多路复用输入/输出的系统调用,允许程序监视多个文件描述符的状态变化。它通过等待文件描述符的可读、可写或异常事件来实现,但本身不负责数据拷贝,拷贝工作由 read 或 write 等系统调用完成。select 函数的原型包括参数 nfds(监听的文件描述符总数)、timeout(超时时间)以及 readfds、writefds、exceptfds(分别表示可读、可写、异常事件的文件描述符集合)。这些集合通过位图表示,系统提供 FD_SET、FD_CLR 等宏操作位图。select原创 2025-05-22 12:54:59 · 897 阅读 · 0 评论 -
【网络编程】十四、五种常见IO模型详解
文章主要介绍了五种常见的IO模型,并通过钓鱼的例子形象地解释了这些模型的工作原理。五种IO模型分别是:阻塞式IO、非阻塞式IO、信号驱动式IO、多路转接式IO和异步IO。其中,前四种属于同步IO,进程或线程亲自参与IO处理;而异步IO则由操作系统处理完成后通知应用程序。文章还强调了IO的本质是“等待+数据拷贝”,提高IO效率的关键在于减少等待时间。此外,文章还介绍了高级IO中的重要概念,如同步与异步、阻塞与非阻塞的区别,并提到了一些高级IO技术,如非阻塞IO、多路转接等。最后,文章介绍了fcntl函数,用于原创 2025-05-21 10:14:11 · 994 阅读 · 0 评论 -
【网络编程】十三、DNS && ICMP && NAT/NAPT && 代理服务器
域名系统(DNS)是将域名转换为IP地址的应用层协议,基于UDP协议。最初通过hosts文件管理域名与IP的映射,但随着网络扩展,DNS系统应运而生,由组织管理机构维护数据库,自动查询域名对应的IP。域名解析过程包括查询浏览器缓存、操作系统缓存、本地hosts文件、本地DNS服务器,直至根DNS服务器和顶级DNS服务器。使用dig工具可以分析DNS解析过程。当在浏览器输入包含域名的URL时,会触发DNS查询,随后通过TCP/IP协议与服务器通信,获取并显示网页内容,包括静态资源和通过AJAX进行的异步请求。原创 2025-05-20 09:22:10 · 806 阅读 · 0 评论 -
【网络编程】十二、两万字详解 IP协议
网络层负责将数据从一台主机传输到另一台主机,主要解决数据路由问题。数据在传输过程中需要经过封装、路由和解包的过程,类似于从一栋楼到另一栋楼的路径选择。网络层通过路由器进行路径选择,路由器通过路由表找到最短路径。IP协议是网络层的核心协议,其报头包含版本号、首部长度、服务类型、总长度、标识、标志、片偏移、生存时间、协议、首部检验和、源IP地址、目的IP地址等字段。IP协议通过定长报头和自描述字段的方式分离报头和有效载荷,并根据协议字段决定将有效载荷交付给上层的哪个协议。原创 2025-05-19 11:22:43 · 1141 阅读 · 0 评论 -
【网络编程】十一、四万字详解 TCP 协议
TCP协议是互联网中广泛使用的传输层协议,主要提供可靠性保证,广泛应用于HTTP、HTTPS、FTP等上层协议。网络中的不可靠性源于长距离数据传输中可能出现的各种问题,TCP协议通过复杂的机制确保数据无差错、不丢失、不重复且按序到达。相比之下,UDP协议简单但不保证可靠性,适用于允许少量丢包的场景。TCP的主要特点包括面向连接、可靠交付、全双工通信和面向字节流。TCP报文段的首部格式包含源端口、目的端口、序列号、确认应答号、首部长度、标志位、窗口大小和检验和等字段,这些字段共同确保TCP协议的功能实现。原创 2025-05-17 15:58:47 · 620 阅读 · 0 评论 -
【网络编程】十、详解 UDP 协议
传输层是网络协议栈中的关键部分,负责在主机之间提供可靠的数据传输服务。它通过端口号标识应用进程,实现数据的复用和分用。传输层协议如UDP和TCP,确保数据从源主机正确传送到目标主机。UDP协议以其简单性和高效性著称,适用于对实时性要求较高的应用。UDP首部包含源端口号、目的端口号、报文长度和检验和等字段,确保数据的基本传输需求。端口号的引入解决了进程标识符在网络通信中的不稳定性问题,使得网络通信更加可靠和高效。通过五元组(源IP、源端口、目的IP、目的端口、协议号)可以唯一标识一个通信会话,确保数据正确交付原创 2025-05-16 23:14:37 · 1378 阅读 · 0 评论 -
【网络编程】九、详解 HTTPS 加密原理
HTTPS 是在 HTTP 基础上加入 SSL/TLS 加密层,解决了 HTTP 明文传输的安全问题,如窃听、篡改和冒充风险。HTTPS 通过加密、校验机制和身份证书保障数据安全,其默认端口为 443,而 HTTP 为 80。HTTPS 在 TCP 三次握手后还需进行 SSL/TLS 握手,确保通信安全。加密和解密过程中,对称加密使用同一密钥,速度快但安全性较低;非对称加密使用公钥和私钥,安全性高但速度慢。数据摘要(如 MD5、SHA)用于验证数据完整性,不可逆且常用于文件比对和密码存储。HTTPS 的广泛原创 2025-05-15 16:19:22 · 1330 阅读 · 2 评论 -
【网络编程】八、Cookie && Session && 抓包原理
HTTP协议本质上是无状态的,每次请求或响应之间没有关联,导致服务器无法识别客户端身份,影响用户体验。为解决这一问题,引入了Cookie技术,浏览器通过保存用户信息(如账号密码)并在后续请求中自动发送,实现了会话保持功能。然而,Cookie存在安全问题,如信息泄露和伪造风险。为进一步提高安全性,引入了Session机制,服务器生成并管理Session ID,用户通过Cookie保存Session ID,服务器通过验证Session ID进行身份识别。尽管Session机制提高了安全性,但仍面临伪造攻击等风险原创 2025-05-14 13:00:44 · 1088 阅读 · 0 评论 -
【网络编程】七、详解HTTP && 搭建HTTP服务器
这个要从万维网说起!万维网WWW(World Wide Web) 是一个大规模的、联机式的信息储藏所,英文简称为 Web,而不是什么特殊的计算机网络。它提供了一种链接的方式,能够非常方便地从互联网上的一个站点访问另一个站点,从而主动地按需获取丰富的信息,具体的细节我们这里不展开讲! 同时万维网也是一个 分布式的 超媒体(hypermedia)系统,它是 超文本(hypertext)系统的扩充。所谓超文本是指包含指向其它文档的链接的文本,也就是说,一个超文本由多个信息源链接成,而这些信息源可以分布在世界原创 2025-05-13 13:17:36 · 1264 阅读 · 0 评论 -
【网络编程】六、序列化与反序列化 && 定制协议
文章主要介绍了协议、序列化与反序列化的概念及其应用,并通过自定义协议实现一个网络版计算器的案例进行说明。 协议:协议是计算机系统或网络设备之间通信的规范,定义了数据格式、传输方式、错误处理等,确保不同设备能够正确交换信息。常见的协议包括TCP/IP、HTTP、SMTP等。 序列化与反序列化:序列化是将对象转换为字节流以便传输或存储,反序列化则是将字节流还原为对象。序列化通常使用二进制格式,常见的序列化工具有JSON、XML、protobuf等。 自定义协议实现网络版计算器:通过自定义协议,实现了一个简单的网原创 2025-05-12 10:27:34 · 1111 阅读 · 0 评论 -
【网络编程】五、三次握手 && 四次挥手
本文详细介绍了TCP协议中的三次握手、通信过程以及四次挥手的机制。首先,三次握手通过客户端和服务端的SYN和ACK报文段建立连接,确保双方进入ESTABLISHED状态。接着,通信过程中,客户端和服务端通过send()和recv()函数进行数据传输,体现全双工通信特点。最后,四次挥手通过FIN和ACK报文段逐步关闭连接,客户端进入TIME_WAIT状态等待2MSL时间后释放连接,服务端在收到确认后直接进入CLOSED状态。整个过程确保了TCP连接的可靠性和有序性。原创 2025-05-10 09:15:18 · 1156 阅读 · 0 评论 -
【网络编程】四、守护进程实现 && 前后台作业 && 会话与进程组
守护进程(daemon)是一种在后台运行的特殊进程,通常在系统启动时启动,并在系统关闭时终止。它不与用户交互,也没有控制终端,通常以超级用户权限运行,用于执行特定任务或提供服务,如网络服务、系统监控等。守护进程的关键特点是能在系统崩溃或重启后自动恢复,确保服务连续性。会话(session)是一个或多个进程组的集合,包含一个前台进程组和多个后台进程组。会话中的进程组可以通过 shell 命令进行前后台切换,作业可以通过 fg 和 bg 命令在前后台之间转换。前台进程组负责与用户交互,而后台进程组则在后台执行原创 2025-05-09 07:36:55 · 1234 阅读 · 0 评论 -
【网络编程】三、TCP网络套接字编程
否则这个执行函数的第一个参数是隐藏的 this指针,就会报错! 但在线程的执行例程当中会调用。原创 2025-05-08 08:41:58 · 1212 阅读 · 0 评论 -
【网络编程】二、UDP网络套接字编程详解
UDP相当于 TCP来说细节少了很多,所以我们先从简单的 UDP套接字编程下手,因为其涉及到的细节比较少,也很直接,就是面向报文,服务端拿到信息就直接丢给客户端,丢了也不管,无需我们关系太多细节,等我们把 UDP套接字编程稍微掌握了,其实 TCP的那套接口也是类似的,但是我们学 TCP的时候,需要去了解它的传输细节。 下面我们就从 UDP套接字编程开始,分为服务端和客户端,我们先讲服务端,客户端也就顺其自然了解了!原创 2025-05-07 22:52:38 · 1460 阅读 · 0 评论 -
【网络编程】一、socket编程详解
因特网上的每台计算机都有一个唯一的 IP地址,如果一台主机上的数据要传输到另一台主机,那么对端主机的 IP地址就应该作为该数据传输时的目的 IP地址。但仅仅知道目的 IP地址是不够的,当对端主机收到该数据后,对端主机还需要对该主机做出响应,因此对端主机也需要发送数据给该主机,此时对端主机就必须知道该主机的 IP地址。因此一个传输的数据当中应该涵盖其源IP地址和目的IP地址,目的 IP地址表明该数据传输的目的地,源 IP地址作为对端主机响应时的目的 IP地址。原创 2025-05-06 11:02:44 · 1088 阅读 · 0 评论 -
【多线程】九、常见的锁 && 读者写者问题
类型声明如下(注意在linux 2.6内核中,编译带读写锁数据类型时需要加参数,否则会编译错误)structint __lock;// 锁的状态// 读者数量// 读者的唤醒标志// 写者的唤醒标志// 等待读者的数量// 等待写者的数量// 用于存储读写锁的标志位// 当前写者的ID} __data;// 用于计算pthread_rwlock_t的大小// 用于内存对齐其中上述的 __flags。原创 2025-05-05 14:02:00 · 940 阅读 · 0 评论 -
【多线程】八、线程池
线程池是一种多线程的并发模型,它包含了一组线程,用于执行多个任务,通常将任务存储在队列或者数组中,并通过一定的调度算法来实现任务的执行。线程池可以提高应用程序的性能,减少线程的创建和销毁所带来的开销,并能更好地控制并发线程的数量,从而避免因线程过多而导致系统性能下降的问题。加上一个或一个以上的线程实现,线程池中的线程可以从阻塞队列中获取任务进行任务处理,当线程都处于繁忙状态时可以将任务加入阻塞队列中,等到其它的线程空闲后进行处理。需要大量的线程来完成任务,且完成任务的时间比较短。原创 2025-05-04 10:50:54 · 662 阅读 · 0 评论 -
【多线程】七、POSIX信号量 && 环形队列的生产者消费者模型
CAS是一种常见的原子操作,也称为“比较-交换”操作,是一种比较后数据若无改变则交换数据的一种无锁操作(乐观锁)。用于实现多线程或多进程并发访问共享资源的原子性操作。 CAS操作通常有三个参数:共享变量的内存地址、期望值和新值。CAS操作首先比较共享变量的值是否等于期望值,如果相等,则将共享变量的值替换为新值;如果不相等,则不执行任何操作。在这个过程中,CAS操作具有原子性,即其他线程或进程无法同时访问共享变量,从而避免了竞态条件和数据竞争等问题。 CAS。原创 2025-05-03 21:34:49 · 906 阅读 · 0 评论 -
【多线程】六、基于阻塞队列的生产者消费者模型
举个例子,生产者就是工厂,消费者就是我们日常消费的人,一般来说,我们是不会直接去工厂买东西的,而是到超市去买,超市就相对于是一个缓冲区,我们每次买东西的时候都会去超市买,超市一般都会储备比较多的货,所以消费者一般不需要去关心是否有货的问题; 要知道,其实这种模型是串行的方式通过阻塞队列的,所以其实相对于生产者直接向消费者投递资源、消费者直接向生产者拿资源来说其实效率不是高的很明显,而关键提高效率的要点在于生产者投放资源是需要消耗时间的,这段时间对于其它的生产者来说是不影响的可以继续投放,提高了效率;原创 2025-05-02 20:21:58 · 1260 阅读 · 0 评论 -
【多线程】五、线程同步 && 条件变量
/ 用于实现对条件变量的互斥访问// 一个底层的系统调用,用于实现线程等待和唤醒,它是一个用户空间和内核空间之间的交互接口,用于实现线程的同步和通信// 记录条件变量被唤醒的次数,包括所有线程的唤醒次数// 记录条件变量被唤醒的次数// 最后一次被唤醒的时间戳// 与条件变量相关联的互斥锁的指针/地址// 记录当前等待的线程数// 记录最后一次broadcast的时间戳} __data;// 指定条件变量的大小// 指定该类型的对齐方式。原创 2025-04-26 15:00:36 · 787 阅读 · 0 评论 -
【多线程】四、死锁
这些资源可能是共享的,如内存、硬盘等,或者是独占的,如打印机、数据库等。银行家算法的思想是为了避免出现“环路等待”条件,它采用安全性检查的方式来避免系统进入不安全状态,从而保证资源的安全分配。该算法把执行流和资源分别表示为图的顶点,用有向边表示执行流对资源的请求以及资源的分配。如果一个进程在一定时间内无法获取所需的资源,就会自动放弃这个请求,并释放已经占用的资源,从而避免死锁的发生。 是的,但是一般在大工程中,两个重复加锁的代码之间可能隔着很多行代码,导致疏忽的加锁,这都是有可能的,这都是。原创 2025-04-25 11:20:16 · 995 阅读 · 0 评论 -
【多线程】三、线程互斥 && 互斥量操作 && 守卫锁 && 重入与线程安全
定义互斥锁对象 其中 pthread_mutex_tstruct{int __lock;// 锁的状态值,用于表示锁是否被占用。// 锁的计数器,用于支持可重入锁。// 锁的拥有者线程ID。/* KIND必须保持在结构中的这个位置,以保持二进制兼容性 */int __kind;// 锁的类型,包括PTHREAD_MUTEX_NORMAL(普通锁)、PTHREAD_MUTEX_RECURSIVE(可重入锁)等。// 锁的使用者数,用于支持可重入锁。原创 2025-04-24 17:32:47 · 1383 阅读 · 0 评论 -
【多线程】二、pthread库 && 线程控制 && 线程分离 && __thread关键字 && 线程库封装
应用程序应该使用 POSIX线程库提供的函数来操作 pthread_t类型的值,而不是直接访问或修改它的内部成员。因此,虽然 pthread_t类型在定义时被 typedef为无符号长整型,原创 2025-04-23 15:15:30 · 787 阅读 · 0 评论 -
【多线程】一、线程的概念与特点
我们已经将页表的工作原理这个坑填上了,接下来就是学习真正的多线程部分,而这部分的知识可能会与我们之前学的进程有些出入,但是在进程部分的知识大部分还是成立的,只不过我们之前讲的那种进程是比较特殊的,也就是单执行流进程,而从现在开始,一个进程就不再是单执行流了,而是多个执行流,也就是多线程!线程是操作系统中能够独立运行的最小单元,它是在进程内部创建的执行流,与同一进程中的其他线程共享进程资源。与进程不同的是,线程没有独立的地址空间和系统资源,线程的创建、撤销和切换都由操作系统内核完成。原创 2025-04-22 09:13:20 · 926 阅读 · 0 评论 -
【进程信号拓展】SIG_CHLD 信号处理
函数清理僵尸进程,父进程可以阻塞等待子进程结束,也可以非阻塞地查询是否有子进程结束等待清理(也就是轮询的方式)。采用第一种方式,父进程阻塞了就不能处理自己的工作了;采用第二种方式,父进程在处理自己的工作的同时还要记得时不时地轮询一 下,程序实现复杂。信号的处理函数,这样父进程只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用 wait。信号,该信号的默认处理动作是忽略,父进程可以自定义 SIGCHLD。 其实,子进程在终止时会给父进程发 SIGCHLD。原创 2025-04-21 08:50:23 · 494 阅读 · 0 评论 -
【进程信号拓展】可重入函数 && 不可重入函数 && volatile关键字详解
不是的,我们目前大部分使用的接口都是不可重入函数,特别是 STL 中的容器有各种涉及插入、删除等操作,它们都是不可重入函数, 这是一种特性,是中性词,而不是问题! 所以它不需要我们去解决,我们只需要理解它们的特性即可!原创 2025-04-20 08:31:19 · 1161 阅读 · 0 评论 -
【进程信号】五、信号集操作接口详解
❓❓❓ 答案肯定还是。原创 2025-04-19 20:45:49 · 1106 阅读 · 0 评论 -
【进程信号】四、信号的捕捉
当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。原创 2025-04-11 14:51:48 · 993 阅读 · 0 评论 -
【进程信号】三、阻塞信号
首先我们先要定位到是几号信号,比如我们使用 signal(2, mySigHandler),那么就会去找到信号表中的 2。原创 2025-04-10 14:51:43 · 964 阅读 · 0 评论 -
【进程信号】二、信号的产生
提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉信号!并且值得注意的是,既然采用了自定义的函数来处理信号,那么原来的那个默认处理,就不存在了! 💥除此之外,系统对于9号信号19号信号等信号,是一定会将该进程终止掉的,因为如果我们在自定义9号信号处理的时候如果不退出,那么就会导致进程无法杀掉,最后系统会崩掉,为了防止发生这种情况,OS调用9号信号的时候肯定是会将对应的进程杀掉的,不存在说不杀掉的情况!// 自定义处理信号的函数。原创 2025-04-08 10:32:07 · 700 阅读 · 0 评论 -
【进程信号】什么是信号?
我们下面先引出生活的几个共识: 在我们生活中,信号不外乎就是这些:发令枪、闹钟、红绿灯、消息提醒、手机铃声等等,那我们想一下,以红绿灯为例子,为什么人能够识别红绿灯呢❓ 其实可以将识别分解为①认识+行为产生,我们因为有人教育过我们,让我们在大脑中记住了对应的红绿灯的属性,所以知道这是红绿灯,就像那些贫困地区的人可能没去过交通发达的地方,可能没有红绿灯,所以可能不知道红绿灯是什么!原创 2025-04-07 10:11:29 · 675 阅读 · 0 评论 -
【Linux进程通信】四、System V IPC
这里我们介绍的这种通信方式也就是 system V IPC在我们后面的使用和日常见到的其实并不多,但是包括其中的共享内存、消息队列、信号量,我们如果了解共享内存其原理的话,能够更好的帮助我们了解之前我们学过的进程地址空间的概念! 至于信号量,我们后面讲多线程的时候会再次讲,我们只引入一些概念如互斥等等,而消息队列我们就只说说其原理,不会细讲!原创 2025-03-20 13:05:39 · 1132 阅读 · 0 评论 -
【Linux进程通信】三、命名管道
其实就是因为操作系统知道这是一个管道文件,知道这个文件是管道类型,所以对于管道文件和普通文件的处理方式不一样,对于普通文件来说它加载到内存中,我们不断的向普通文件里面写入数据,它是会不断的刷新到磁盘上的(与刷新策略有关),所以如果这里是普通文件的话那么我们会看到大小一直在变;语言编写的头文件,通常用来定义数据类型,声明变量、函数、结构和类),所以在程序中要实现的话,我们就得用在程序中创建管道文件的语言级别接口 mkfifo。指令一次,就不断的循环将写入管道的数据一个一个的读到屏幕上面,原创 2025-03-17 13:22:47 · 800 阅读 · 0 评论 -
【Linux进程通信】二、匿名管道
当没有数据可读时read调用阻塞,即进程暂停执行,一直等到有数据来到为止read调用返回-1errno值为EAGAIN当管道满的时候write调用阻塞,直到有进程读走数据:调用返回-1errno值为EAGAIN如果所有管道写入端对应的文件描述符被关闭,则读取端read返回0如果所有管道读取端对应的文件描述符被关闭,则 write操作会产生信号 SIGPIPE,进而终止写入端write当要写入的数据量不大于 PIPE_BUF时,linux将保证写入的原子性。原创 2025-03-14 13:17:44 · 710 阅读 · 0 评论 -
【Linux进程通信】一、进程间通信的概念
之前我们学习了进程以及基础IO的相关知识,所以进程之间我们知道都是具有独立性的(通过写时拷贝和虚拟地址空间),那么如果我们今天想让不同的进程之间进行资源的交互,也就是说进程A想看到进程B发过来的信息并及时接收它,那么我们仔细想想这不就是和进程的独立性相违背了吗 ❓❓❓ 因为我们之前说,如果打开一个文件,并且父进程创建了子进程,那么子进程其实就会拷贝父进程的大部分属性和内容,包括文件描述符表等,也就是说如果父进程指向了一个打开的文件,那么子进程也是会指向那个打开的文件。原创 2025-03-12 13:21:00 · 731 阅读 · 0 评论 -
【Linux系统IO】六、动静态库
我们之前学 gcc的时候也有接触过一点动静态库的知识,现在要把它单独拿出来讲,主要是因为我们后面肯定在自己开发的时候需要包装自己的库,此时就需要有动静态库的原理知识和使用知识!一般库名称都是中间部分,也就是去掉前缀和后缀的部分剩下的内容,如:libc.so,去掉前缀 lib,去掉后缀 .so-> c动态库。问题来了:为什么需要库呢❓❓❓ 我们给使用者提供我们写的函数的时候,一般是不会将源代码发给他们的,所以都会将 .c文件或者其它文件编译成可重定位目标二进制文件也就是 .o。原创 2025-03-10 21:21:50 · 929 阅读 · 0 评论 -
【Linux系统IO】五、软硬链接
比如桌面看到的软件保存的是其它的路径,在系统中可能你要运行的可执行程序在一个很深的目录下,就可以在较上层的目录中建立软链接来直接使用。 可以发现硬链接依然能够看到文件的内容,但是软链接已经失效了,因为软链接中存放的是原来源文件的路径,现在源文件没了,当然就找不到了,也可以侧面说明。的概念,也就是说,创建一个硬链接其实就是多了一个指向源文件的一个引用,对于目录来说,只会多添加了一个 inode。,通过保存的路径访问源文件,因此源文件被删除则无法再访问,通过路径将找不到源文件,这时候软链接就会失效。原创 2025-03-07 13:49:25 · 1043 阅读 · 0 评论 -
【Linux系统IO】四、文件系统
之前我们学习的都是进程与被打开文件的关系,但是那些没有被打开的文件呢,它们需不需要被管理呢 ❓❓❓ 答案肯定是需要的,对于一台计算机来说,磁盘上大部分的文件是未被打开的,而这些文件也需要被静态管理起来,方便我们随时打开!操作系统对未打开文件与打开文件的管理,称为文件系统。接下来我们就来学习未打开文件的管理! 我们大部分人日常中都没见到过磁盘的真实面目,所以如果要想了解文件系统,我们势必要先了解磁盘的简单物理结构,方便我们理解操作系统层面!原创 2025-03-05 13:40:43 · 944 阅读 · 0 评论 -
【Linux系统IO】三、缓冲区
先来看看下面的代码: 目前打印结果和重定向到文件中都是按我们的预期执行的,接下来我们在代码的最后 一下,看看发生什么: 嘶,是不是很奇怪,为什么 之后,向文件里面输出之后居然多了一倍的数据,我们 明明是在输出完之后执行的啊,并且就算是都打印了两倍,那为什么 只被输出了一次 ❓❓❓ 其实这一切都和 以及 有关系,下面我们就来正式介绍一下缓冲区! 首先我们要知道,缓冲区的本质就是一段用作缓冲的内存,下面我们举个例子来解释一下为什么要有缓冲区! 我们在生活中总是需要去买东西或者寄东西原创 2025-03-03 14:02:50 · 1095 阅读 · 0 评论 -
【Linux系统IO】二、文件描述符与重定向
简单地说,文件描述符fd的本质就是数组的下标若一个文件被打开,那么肯定会有一个相对应的文件描述符字段给到该文件,用于标识该文件! 既然是数组的下标,那么是什么数组呢 ❓❓❓ 其实在 linux底层中是这样子的,每个进程的进程管理块 task_struct中包含着一个 struct files_struct* files指针指向 files_struct这个结构体,这个结构体也称为 文件描述符表,其中这个结构体中包含着一个指针数组 struct file* fd_array[]原创 2025-03-01 14:12:48 · 959 阅读 · 0 评论