自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(181)
  • 收藏
  • 关注

原创 GTest测试框架介绍

GTest是谷歌发布的一个跨平台的单元测试框架,主要是为了在不同平台上编写的C++单元测试而生成的。测试中可以有多个测试套件,可以包含一组单元测试,不是很好理解,可以认为这是一个测试环境。测试程序中可以有很多测试套件,对应着全局,每一个测试套件中可以有多个单元测试。这其实就是我们用户自己定义的一个测试环境,是一个全局的测试环境类。如果局部需要设置全局的环境,就需要使用之前的全局的继承。在用例测试中,每一次单元测试都是单独进行的,互不影响。提供了丰富的断言,致命和非致命的判断,参数化。

2024-10-01 16:28:39 194

原创 SQLite数据库介绍

SQLite是一个本地化的数据库,不需要客户端服务端什么的配置,主打就是轻量化方便化。他也不是一个独立的进程,而是可以根据应用程序的需求,可以进行静态或者动态的连接。第三个参数是flag是可以设置文件的打开方式,提供下面的宏可以选择。需要注意的是 在SQLite中一个数据库对应了一个数据库文件。而且他是直接存储在磁盘文件的,提供了简单易用的API接口。第一个参数是文件名,第二个参数是传入一个句柄指针的地址。如果是其他值的话就代表着有问题,需要查找对应的宏来看到。这是一个执行语句的操作函数。

2024-09-30 19:32:06 306

原创 基于muduo库实现protobuf协议的通信详解

而在这个类中,我们可以看到onMessage和send,其实就是针对protobuf处理的方法,也就是收到消息之后被调用的方法。在之前我们单纯使用muduo实现的时候,并没有考虑到tcp粘包之类的问题,只是进行一个返回。可以看到这里消息回调函数,这里面用的是ProtoBufCodec的onMessage函数。在具体看这个onMessage处理函数之前,我们先看这个协议的结构是什么样的。我们可以先大致学习一下这里是怎么实现的,然后仿照使用一下。有了这样的协议之后,就可以解决粘包问题。业务操作逻辑是这样的。

2024-09-30 14:28:36 419

原创 C/C++static关键字详解

static的意思是静态的一开始在学习C语言时,我们时用它来控制变量和函数的作用域,也就是使用范围,后面学习到进程地址空间,才了解到他也改变了存储的区域我们知道进程地址空间可以大致分为栈区、堆区、静态区诶这个静态区是不是眼熟,没错static修饰的变量都存在静态区,一直到程序结束时才会释放额外bb一句,所有的常量也存在静态区简单说,static修饰的对象无非就是变量和函数,但是变量和函数放的位置不一样,static的作用也不一样C语言中static一共有三个用法这里对函数和全局变量的限制是相同的,目前还没有

2024-09-30 12:04:20 470

原创 MySQL数据库基础

在过去的mysql中主要是使用的utf8mb3,但是mysql显示的就是utf8,中mysql8中区分显示了。类似于不同的编译器,虽然C/C++的代码是一样的,但是预处理、编译、汇编、链接这些过程却不尽相同。而校验规则主要是区分查的规则,有的规则区分大小写,有的规则不区分,会有一部分的性能差异。之前我们虽然学习了数据库的基本操作,但是如果想要了解底层的部分,还是需要理解原理的。如果真是这样简单使用,那确实,但是如果想要能把数据库用好,其实也是不容易的。先不说够不够用,且说增删改查,改和查其实是最麻烦的。

2024-09-30 12:02:27 942

原创 muduo网络库介绍

在主线程中主要任务就是监控新连接的到来,保证尽可能高效的获取新建连接,再按照负载均衡的方式分发到普通Reactor的线程中,对对应的IO事件进行监控。这个类主要是用于事件监控和业务处理,在构造TcpServer之前,就需要构造这个EventLoop对象,最重要的就是loop成员函数。所谓的主从Reactor就是,在主线程中有一个主Reactor进行事件触发,而在其他其他线程中就是普通的Reactor进行事件触发。这是一个非阻塞接口,调用之后直接返回,连接不一定建立完成,不能直接发送数据。

2024-09-28 14:42:15 917

原创 Linux高级IO之poll与epoll

epoll的默认工作模式就是水平触发,当epoll检测到事件就绪时,可以不立即进行处理,或者仅处理一部分,一直到缓冲区的所有数据都被处理完,才不会立即返回,支持阻塞和非阻塞。poll和epoll都是多路转接的调用,但是epoll实在过于优秀了,一般也都是用epoll的,除此之外还着使用时还蕴含着Reactor设计模式的思想。边缘触发就是类似于非阻塞的情况,事件发生时,只通知一次,爱拿不拿,不保证数据依然还在,你只有一次处理机会。events表示事件发生时要做的操作,也就是需要监听的事件。

2024-09-27 19:36:56 848

原创 Linux高阶IO之select多路转接

select能够同时监视多个文件描述符,但是也总是有上限的,上限就是fd_set位图的大小除此之外,我们不仅需要维护fd_set,还需要额外维护放入fd_set中的数据集,否则我们无法使用FD_ISSET判断文件描述符是否就绪而且每一次都需要重新逐一加入fd_set,然后再取出最大的文件描述符,作为第一个参数输入所以这个系统调用是真难用,非常不便,还需要将fd_set从用户态拷贝到内核态,fd_set也不够大但是这是第一个,有缺陷才是正常的,后面才会越来越好,有了poll和epoll。

2024-09-26 16:41:11 319

原创 Linux高级IO之五种IO模型

而交换则对应了输入和输出两个部分,由于计算机网络的影响,IO也不应当狭义的理解为从内存中IO,而应当也扩展至从网络中IO,虽然设备上,是内存和网卡的区别,但是对于Linux来说他们都是文件,是没什么区别的。在IO时,一共做了两件事情,第一件事情是等待,等待缓冲区的文件,或是网卡上来,或是从内存中来,第二件事情是拷贝,将缓冲区数据拷贝到内存中。类似于计算机发展的过程,计算机开始时是等待IO和处理数据两个过程,然后逐步演化为现在的并发情景,将等待IO的时间减少,处理数据的时间增加。

2024-09-26 12:16:01 852

原创 Linux网络之UDP与TCP协议详解

这段时间服务器什么也没有等到,服务器说,这是我跟你说的最后一句话,以后再也没有了(假),拜拜(发送了一个LAST_ACK,表示最后一个ACK报文,并且附带了FIN标志,表示结束)如果服务器发送了1到20号数据,但是客户端收到的是1和3到20,只发了一个2的请求,服务器看到之后觉得他只收到了1,于是把2到20又发了一遍,这样的效率又变得不行了。这里需要知道一点,当我发出一条消息的时候,我是不知道这条消息能不能传达到的,但是可以确定的是,我之前的消息一定传到了,并且我也可以收到对方的消息。

2024-09-23 20:38:24 1058

原创 Linux网络——HTTPS详解

这样做,即便是服务器自身想要修改公钥都是不行的,只能向CA机构申请,因为数字签名是由CA私钥生成的,一旦篡改就会被认为不安全。跟随着证书一起发去,当对方收到这些之后,用公钥对数据签名进行解密,然后和证书进行比对,一旦出现差错,就说明证书有问题。流程是这样的,当客户端和服务器第一次交流时,客户端获取到服务器中生成的公钥S,而服务器自身有私钥S’如果说是要掉包证书,不能只改公钥,因为哈希值不一样,他没有服务器的私钥,算不出来正确的哈希值。这样就能确认公钥一定是服务器的而非中间人的了,后面的对称也都是安全的了。

2024-09-23 08:35:01 1134

原创 Linux网络——HTTP协议详解(2)

3开头的重定向操作还是蛮有用的,就类似于手机的呼叫转移,当某一个网站(服务器)暂时无法访问时,可以转接到另一个网站或者服务器,在某些情况下,这种转接甚至是永久的(301)浏览器能记住,也就是cookie,他可以存在内存里,也可以存在一个单独的cookie文件,当账号密码直接以明文的形式存在里面的时候,其实还是不安全。我们需要记住的其实就是大概知道是哪里出问题了,2开头的基本上没问题,3开头是可以重定向操作,4开头就是请求错了,5开头是服务器错误。

2024-09-22 17:48:16 297

原创 ProtoBuf序列化框架介绍

ProtoBuf全称是Protocol Buffer,是一个数据结构的序列化和反序列化框架他又很多好处,首先是他支持跨平台,支持Java、C++、Python等多种语言,还比XML更小更快更简单除此之外还可以更新数据结构,不会破坏原有的结构。

2024-09-21 21:39:04 412

原创 Linux网络——HTTP协议详解(1)

第一行就是请求行,主要有三个内容,第一个是请求方法,这里我们看到是GET,其实还有别的方法,第二个是url,第三个是版本,有1.0短连接,1.1长连接和2.0。HTTP可以说是当今应用最广泛的应用层协议之一,主要面向的是浏览器(客户端)和服务器之间通信的规定。HTTP协议的底层是TCP协议,我们先大概认识一下这个协议是如何使用的。虽然看起来很乱,但是可以分为三个部分,请求行,报头,空行,正文。这里我们写了一个简单的程序,获得了请求的报文,是长这个样子的。,但这个其实是省略过后的,完整的长这样。

2024-09-18 18:31:40 425

原创 Linux网络——手撕TCP服务器,制定应用层协议,实现网络版计算器

我们想发送的数据不一定是单纯的数值、字符,完全有可能是结构体,是类,我们想要传输这些内容,需要做的就是讲这些数据和结构体转换为字节流,这个过程我们称之为序列化。除此之外,既然是面向字节流的,我们如何知道一段数据的开始和结尾呢,就像水流一样,如果不做限制是很难分清的,因此我们还需要在数据的开始和结尾做标识。而且这个序列化和反序列化的过程是必须要相同的规则,不然就像字符串加密解密一样,没办法得到你想要的数据,这个相同的规则规矩,我们就称之为协议。那么反过来,从字节流解释出来各种数据和结构体的过程就是反序列化。

2024-09-17 14:07:07 760

原创 Linux网络——守护进程、会话、进程组

会话是session,代表的是客户端与服务器的一次交互过程,我们可以简单理解为,当我们打开一个终端,在用户登录时,就是创建了一个会话。当Linux系统启动时,或者bash启动时,会启动很多进程服务,例如ssh连接,或者一些代理服务,在进程终止或者系统终止时服务才停止。守护进程也叫做精灵进程,Deamon,是一种运行在后台的进程,所谓前台后台可以简单理解为能否直接收到键盘指令的进程。一个会话中可能有很多进程,我们称之为进程组,为了表示也就有了进程组ID:PGID,会话ID:SIG。

2024-09-15 23:58:46 480

原创 Linux网络——socket编程与UDP实现服务器与客户机通信

在同一台计算机的进程是通过进程id区分的,而要在对方的计算机中按照进程id来找恐怕不是一共好的想法,因为你也不知道对方进程的id是多少,于是就商量(传输层协议)使用port端口来确定进程。除此之外,TCP由于建立了连接,就可以像水流一样传输数据,是面向字节流的,而UDP则没有,所以UDP是面向数据包的。TCP面向的是有连接,意思是在正式的传递信息之前,需要建立连接,确保是能收到的,就像对暗号一样,土豆土豆我是地瓜。这里就是客户机的主体了,里面的代码和注释写的非常详细,主要思路就是初始化,先听,后回复。

2024-09-11 18:53:14 1812

原创 Linux网络——从《计算机网络》到网络编程

计算机网络也是如此,OSI标准将从下向上设计了七层网络模型,他设计的非常非常好,但是在实践中四层模型就能很好的解决问题,也称之为TCP/IP四层模型,在我们学习的过程中将物理层和数据链路层分开,变成五层模型。当应用层的两个进程想要通信时,实际上的数据是自己的电脑从应用层到传输层到网络层到链路层,层层套上自己的包头,让别人认识自己,让对方认识自己。除此之外,我们在组织数据,处理任务的时候,从来都是将大问题化成小问题,解决了小问题再将各个模块拼起来,就成了如今庞大的知识体系。

2024-09-10 21:56:14 1456

原创 Linux多线程——日志任务的线程池实现

我们将之前的所有内容可以串联起来做一个小型项目,非常建议阅读并自行实现,写代码才是学习编程的最好方式。定义一个ThreadData,用于获取当前线程的信息,可以添加别的信息,例如创建时间,运行时间等。主要运用的场景是需要大量现场完成任务,任务完成时间较短,例如WEB服务器中的网页请求。这里主要完善了日志系统写的方式,可以向屏幕输出、单个文件输出、按照等级划分的文件输出。线程池可以说是把之前所有的内容全部串联起来的一个项目。就是创建固定数量的线程,然后往任务列表里推送任务即可。线程池的使用非常简单。

2024-09-08 13:13:42 518

原创 Linux多线程——POSIX信号量与环形队列版本之生产消费模型

上一篇文章的生产消费模型是基于阻塞队列的,而且只用了互斥同步锁的内容,我们感觉效率其实不高,因为需要频繁考虑互斥同步问题。第一个是声明的信号量,第二个是选项,0表示线程间共享,非0表示进程间共享,第三个表示信号量的初始值。除此之外,还需要互斥锁,因为消费者之间和生产者之间也需要互斥访问。在生产者与消费者模型里面,生产者与消费者所认为的资源是不同的。消费者认为数据是资源,因为每次都会拿东西,数据会变少。但是实现的功能是一样的,都是为了解决同步的问题。我们说信号量指的就是资源的数量。发布信号量就是V操作。

2024-09-07 16:00:12 378

原创 Linux多线程——互斥锁的封装与生产消费模型的实现

为了更方便的使用互斥锁,我们把系统提供的互斥锁接口进行封装,并且贯彻一下RAII思想,让我们的使用更加方便。生产者与消费者之间的关系,不允许一边写一边取,这是互斥关系,并且要求先写后取,这是互斥关系。我们这样定义,生产者负责布置任务,然后通过阻塞队列,传递给消费者,让消费者完成任务。生产者与生产者之间的关系,我们不允许两个生产者共同写,他们之间是互斥关系。消费者与消费者的关系,我们也不允许两个消费者共同取,他们之间也是互斥关系。这里的产品可以是很多东西,我们可以认为产品是一个类,这个类可以是一切。

2024-09-06 19:51:43 302

原创 项目日志——日志系统项目

在生产环境中,有时候是不允许我们程序员利用调试器排查问题,不允许服务暂停在高频操作中,少量调试次数并不一定能够复现出对应的bug,可能需要重复操作非常多次的情况,导致效率低下在分布式、多线程代码中,bug更难以定位因此就需要日志系统进行开发问题的排查。

2024-09-04 17:49:36 361

原创 Linux多线程——线程互斥与同步和其他概念

重入指的是,同一个函数被不同的执行流调用时,当一个执行流还没有执行完成,另一个执行流就再次进入的情况。一般来说,函数可重入,那么线程一定是安全的,如果函数不可重入,那么就不允许多线程并发使用。第一个是要初始化的互斥量,我们在调用之前声明一共传入即可,第二个我们传入NULL。进程资源等待的前提是,拿到锁进入临界区,所以wait函数需要条件变量和互斥锁。当互斥量已经被上锁了,这个线程就会被阻塞,等待互斥量解锁。竞态条件指的是,因为时序问题,导致的程序问题。当原来的互斥量没有被加锁,此时加锁就会成功。

2024-09-04 17:27:42 972

原创 Linux多线程——利用C++模板对pthread线程库封装

因为这个类创建之后并没有真正创建线程,没有分配线程id,而Start作为主线程需要完成的任务就是创建新线程,更改线程的运行状态,返回线程创建成功与否。这样一来,作为静态成员函数是无法直接使用类内成员的,也就是无法使用这个回调函数,因此将this指针作为参数传递进去是一个很好的选择。我们使用C++的模板对其封装可以让他的使用更加方便,并且经过测试可以让我们更加直观的了解到线程互斥和同步的重要性。如果我们直观理解的话,其实就是在判断的时候,在五个线程都只剩下了1张票时,几乎同时进了这个判断。

2024-09-03 21:48:27 735

原创 C++单例模式与特殊类的设计

第一种思路就是,禁止直接使用构造函数,只能通过我给你的静态成员函数接口调用,而且必须设置为静态的,如果是非静态成员函数,就首先需要实例化一个对象才能调用,于是就循环调用了。而设计模式就像是武功里的外功,属于是学会了,但是要怎么样才能把这个功力的作用最大化,在哪些条件下用什么样的内功能破解,研究的是这个问题。例如,我想设计一个只能在栈或堆上实例化的类应该怎么做,我想设计一个不能被拷贝或继承的类应该怎么做,这些就是外功,是有固定章法的。在类里面的静态实例主要起声明的作用,初始化静态实例需要在类外做。

2024-08-31 18:55:33 1108

原创 Linux多线程——线程的概念和控制

一共有四个参数,第一个是线程ID,第二个是选项,目前只设置为空指针即可,第三个选项是需要让新线程走的执行流,第四个是传递给其中的参数。那么一个进程他的执行路线至少有一个,也就算做是一个线程,这个进程本身也可以创建分支线程,那么原来的这个进程也就叫做主线程。从操作系统课本里我们可能听说过,线程是一个微缩版的进程,他拥有TCB,不会被分配资源,是CPU进行调度的单位。每一种信号的处理方式都是共享的。在CPU的视角来看,他的所调度的所有单位都是PCB,是同一个进程,CPU也无法分辨他运行的是线程还是进程。

2024-08-28 16:46:03 993

原创 Linux进程信号——信号的捕捉、保存、处理

最本质里面,其实就是在CPU中的CR3寄存器中,表示当前CPU处于什么状态,1表示内核态,3表示用户态,而这个寄存器对于用户也是不可见的,只由操作系统管理。这个位图用来存储收到的信号,0或1表示是否收到,某一个位置表示对应的信号,这个位图也称之为信号集,也就是未决的情况。这个数组是一个函数指针数组,里面的内容是函数指针,下标表示收到n号信号,调用的处理方法就是对应的函数指针。需要注意的是,在使用sigset_t之前,一定要调用前面的任意一个初始化函数,让整个信号集处于确定的状态。

2024-08-27 13:02:46 1087

原创 Linux进程间通信——互斥锁与信号量详解

当P2操作先执行时,进行P操作申请资源,此时P1进程没有释放资源,所以P2进程被阻塞,真正原因其实是因为func1没有被执行,因此所谓的“资源”没有被释放,P2阻塞,于是P1进程运行,只有当P1进程释放资源之后,P2进程才能继续运行func2。这实际上是一种预定操作,虽然现在没有资源,但是我预定好了,并且一直处于等待队列中吗,并且手动block阻塞,不会让其占用CPU,等待释放资源,轮到我了,我再进行唤醒,我自然就可以使用了。也就是先运行的进程,进行V操作释放操作,后运行的进程进行P操作申请操作。

2024-08-27 11:05:38 1145

原创 Linux进程信号——信号的概念与产生

信号本身其实就是一种通知的形式,用户或者操作系统可以通过信号给进程发送信息,让进程来进行处理例如前台进程可以发送一个ctrl + c指令来中断进程我们可以使用kill -l查看进程信号表这些个信号存在文件中,大致可以分为两类,从1到31是标准信号,其余的都是POSIX实时信号,都有不同的含义ctrl + c其实就对应着2号信号Value表示信号编号、Action表示默认行为Term表示终止、Core稍后会讲解。

2024-08-25 12:09:17 701

原创 Linux进程间通信——硬件实现临界区互斥的基本方法

当两个进程都不使用时,lock为false,执行到进入区时,另一个进程不允许再次进入执行,第一个进程检查并上锁后,第二个进程只能等待第一个进程执行完临界区代码。这一段是多进程代码,也就是有两个进程都有相同的这一段,lock是全局变量,true表示临界资源被占用,初始值为false。操作系统有一个系统级的指令是中断指令,主要分为两个步骤,一个是关中断指令,另一个是开中断指令。这是一条硬件指令,TS指令,这条指令是原子操作,也就是原语,不允许被中断。再次强调,这个硬件指令是由硬件指令实现的,并非代码。

2024-08-25 11:21:02 234

原创 Linux进程间通信——软件实现临界区互斥的基本方法

假如P0进程想访问临界区,就先查看P1进程是否想用(flag[1]是否为true),是的话就等待,不是的话就把自己的设为true,然后访问临界区,访问完之后把自己设为false。这就相当于先声明我要拉,后一步检查对方要不要,但是我们继续考虑并发的情况,如果两个进程几乎同时声明自己要拉,检查的时候两个进程都会一直循环等待,结果就导致谁都没办法拉了。这就相当于一个人在拉之前先问一句,你要不要拉,你要拉的话那你先,你不拉那我要拉了,拉完之后跟他说拉完了,你可以去了。

2024-08-21 13:21:54 574

原创 Linux进程间通信——SystemV消息队列与信号量

我们就可以让A进程先使用P操作将资源占据,B进程再使用P操作的时候,发现资源没有了,只能阻塞,直到A进程执行了V操作释放资源,B进程才得以继续运行。互斥在我们生活中也有遇到过,例如手机摄像头,当你打微信视频的时候,就没办法用相机拍照,当一个人用打印机的时候,另一个人就没办法控制。这种资源称之为临界资源,那么共享内存其实就不算临界资源,除非我们也做保护,访问临界资源的代码也称为临界区。当操作取出的接口时,给第一个进程另一个进程的数据块,给第二个进程第一个进程的数据块。

2024-08-20 19:03:26 981

原创 Linux进程间通信——SystemV共享内存

at是attach是关联的意思,因为共享的物理内存是属于操作系统的,我们需要将共享的内存挂载到进程地址空间的共享区,就要用到shamat。对于第一个参数,key是需要确定唯一的,类似于手机号,你自己有,别人不能再有一模一样的,并且别人想要打给你也必须输入一模一样的。shmid是共享内存id,cmd表示操作,buf是用来获取共享内存的属性的,各种属性都存在该结构体里。需要注意的是,共享内存在进程退出时是不会主动释放的,需要用户手动释放,除非系统内核关闭。第三种方法主要是为了确保所使用的共享一定是新鲜的。

2024-08-18 18:39:59 446

原创 Linux进程间通信——命名管道

之前我们使用的都是匿名管道,命名管道与之不同的就是他拥有实体文件,文件类型为p,而且他的文件大小永远为0。当两个进程分别打开管道时,如果分别分配两个缓冲区,连接着管道文件本体,这样实在低效。第一个参数是管道文件,第二个参数是权限,和open系统调用一样。命名管道也称之为fifo,先进先出,也可以理解其是单向的。他的返回值是int类型,返回值为-1时表示出创建管道失败。可以使用系统调用接口,也可以使用C语言接口都是没问题的。这时因为打开文件的同时也打开了缓冲区。创建管道文件完成之后的任务就简单了。

2024-08-17 17:34:55 213

原创 Linux进程间通信——池化技术与模拟实现进程池

这里其实还有一个隐藏起来的bug,就是在第二个子进程以及之后的子进程fork的时候,实际上他拷贝的是父进程的文件描述符表,因此他也存在一个接口指向之前申请的写接口,只有最后一个子进程是只有一个写接口的。蓝色是每一次我们fork子进程和pipe管道之后,需要关闭的接口,因为每一次的读接口都是3,所以从4、5、6以后的分别对应的就是不同的子进程的写管道。子进程的work是一直循环接收父进程传递的消息,若有效接收,则判断是否为任务列表中的任务,然后执行,若父进程写口关闭,则跳出读取循环,关闭子进程。

2024-08-16 16:19:07 726

原创 Linux进程间通信——匿名管道

然后再用fork函数创建子进程,由于子进程是写时拷贝父进程的,因此对子进程来说,他的文件描述符表也有一个读接口和一个写接口是指向匿名管道的。这个pipe函数实际上做了什么操作呢,可以简单理解为,操作系统创建了一个文件,然后再给两个文件标识符,一个用来表示读,一个用来表示写。因此进程间通信还是很必要的,除此之外网络通信中所说的进程间通信本质上也是两个进程进行通信,只不过信息传递经过了繁杂的计算机网络。再深入一点,管道的本质其实就是一个被打开的文件,但同时能被两个进程访问,而且只能一个进程写,另一个进程读。

2024-08-14 20:32:29 470

原创 Linux基础IO——文件系统与动静态库

我们之前所说的文件读写都是通过进程对已经打开的文件进行操作,也就是对操作系统对文件所创建的结构体进行操作那么对于磁盘中没有打开的文件是如何进行管理的。

2024-08-11 15:28:57 1088

原创 Linux基础IO——重定向与文件缓冲区

IO设备的读写速度是远低于内存和CPU的运转速度的,这其实就说明了缓冲区的重要性,不要让CPU和内存频繁访问IO设备,多和文件缓冲区打交道,当满足条件的时候,一起传递给外设即可。其实就是跟我们前一节内容所讲的一样,通过修改文件描述符表,修改文件描述符到指定文件的指针即可,也就是修改文件描述符下标为1的数组内容,改成到你想要的文件即可。我们就可以推断出,C语言提供的所有IO相关函数都与系统调用的接口对应,从本质上,所有访问文件的操作都是通过文件描述符fd来访问的。我们在学习Linux的基本内容时候,知道。

2024-08-07 19:38:12 339

原创 Linux基础IO——文件的系统调用与文件描述符的本质

C语言打开文件的函数是fopen,读取是fread、fscanf、fgets,写入是fwrite、fprintf、fputs,和基础的scanf、gets使用都是一致的,只需要在末尾加上写入的文件指针即可。可以从键盘读入,显示器输出,也可以输出到文件中,那么其实在操作系统内部,他是把显示器、键盘等外设也看作是文件,向显示器输出和向磁盘文件中输出写入是没有本质区别的。write是写入数据,写入的内容是buf,写入的字节数是count,调用成功就返回文件中的字节数。

2024-08-05 17:35:53 399

原创 Linux进程控制——进程程序替换、bash的模拟实现

其实在Linux环境下,程序替换不仅可以替换C语言程序,甚至可以替换成Python程序、Java程序去执行他们的内部代码,这就变相实现了不同语言之间的联动。我们之前介绍过内建命令,说这种命令只能让父进程调用,例如cd命令,因为写时拷贝,子进程进了某个文件夹,对父进程是没有影响的,也只有在父进程执行才有意义。这是里面最简单的函数,他的函数有两个,第一个是执行的程序路径,之后的是参数包,表示如何执行该程序。这里一共有六个函数,但是是同一个系列的,也有一定的规律,如果他们替换失败了,返回值都是-1。

2024-08-01 18:21:30 419

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除