自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 MySQL事务

我们来学习MySQL事务什么是事务?事务就是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部 失败,是一个整体。MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的 数据是不相同的。事务就是为了完成某项任务的逻辑相关的MySQL语句的集合。事务就是要做的或所做的事情,主要用于处理操作量大,复杂度高的数据。

2025-05-08 18:42:49 659

原创 MySQL的数据类型

我们今天来学习MySQL的数据分类。数据类型分类MySQL的字符型就是相当于字符串类型,所以MySQL没有字符这种说法,这个是和其他语言不一样的地方,单引号和双引号引起来的都是字符串。数值类型MySQL数值类型中整型的取值范围和C语言中的是一样的。我们接着只选择一些有代表性的类型进行讲解。tinyint我们可以称tinyint为微整型,从上表来看这个是整型里面最小的。

2025-04-28 20:30:21 1084 1

原创 (MySQL)表的操作

使用alter table ... add引导的插入一个新的列的语句,指定在哪个表上插入之后add后面写入新的字段名连带着类型,至于注释,约束可以不带,最后是指定这个新插入的列的位置,可以使用after+原有字段名表示插入在这个字段名之后,如果没有指定位置就默认添加到最后一列。[temporary]的意思就是暂时的,加上这个字段的意思就是只删除开启的临时的当前表的会话窗口而不会真的删除存在数据库的同名的真实的表。这次不指定位置就自动插入在结尾,并且插入非空约束,插入新字段后,对原来表中的数据没有影响。

2025-04-27 22:42:06 814

原创 (MySQL)库的操作

就是根据数据库名,删除对应的数据库,如果待删除的数据库存在则执行完后数据库内部看不到对应的数据库,对应的数据库文件夹被删除,级联删除,里面的数据表全部被删,所以可以添加字段约束[IF EXISTS]表示判断是否存在。大写的表示关键字,都可以使用小写,[] 是可选项,CHARACTER SET: 指定数据库采用的字符集,COLLATE: 指定数据库字符集的校验规则,然后[IF NOT EXISTS]是指明数据库不存在才创建。注意,由于MySQL内部的数据库有很多,所以查看时记得是databases。

2025-04-25 13:05:52 966

原创 网络基础2

mac地址是在局域网标识一台主机的唯一性,二者的本质区别就是,一个报文从发送到被接受时,其携带的源ip地址和目的ip地址一般是不变的,假设这个报文需要通过主机或者路由器中转,那mac地址会由于中转的作用而发生改变,每经过一个路由器或者主机其源mac地址和目的地址就会发生改变,一般经过路由器时会重新分配mac帧,此时变成跨网段通信了,mac地址的格式就发生了比较大的改变,这时这个mac地址就不属于原本的局域网的了。我们整个的课程,凡是提到 IP 协议,没有特殊说明的, 默认都是指 IPv4。

2025-04-13 22:35:00 1465 2

原创 网络基础1

以打电话为例,语言层这层和通信设备层这层是分开的,我们打电话只需要向电话说出我们要说的东西,别人也这么说这是语言层的交流,但是实际上我们相互交流的那些话都是通过下层的通信设备层的那些设备进行传输的,这些设备遵循电话机协议实现,所以可以互通,我们在拿着电话交流的时候是不需要管下层那些设备有没有传输的,下层的那些设备是不需要管我们讲了什么的,反正只负责传输,将庞大系统分解为多个层级,每层只需关注自身职责(如网络协议中,应用层处理业务逻辑,传输层管理可靠性),软件分层实际上就降低了设计的复杂度。

2025-04-13 14:16:03 624

原创 其他常⻅的各种锁

写者进入内存中的某块空间中写,为了防止某个写者写的时候不被其他进来的写者打断,如果还没有写完,突然又来了一个写者就很容易导致当前写者被打断或者写的东西被覆盖导致数据丢失,所以写者和写者之间是互斥的关系,读者和消费者最大的不同就是不会拿走写者写的数据,读者只是一味的读,所以这个模型是可以兼容很多个读者一起来读的,反正你读你的,我读我的,我们读的都是内存中的某块空间的内容,读者和读者是并发的,读者和写者之间的关系是互斥和同步的,为什么互斥呢?通常而言,在读的过程中,往往伴 随着查找的操作,中间耗时很长。

2025-04-03 00:27:48 910

原创 单例模式与线程安全

就是多个线程申请多个未释放的锁,然后他们各自却持有这些锁(未解锁),导致都需要等待对方释放,比如A线程持有锁a,B线程持有锁b,那B今天来申请锁A,A申请锁b,这样A,B线程都需要各自等待对方释放才能申请成功,跟那个shared_ptr的循环引用无法释放一样的道理。第⼀次调⽤GetInstance的时候,如果两个线程同时调⽤,可能会创建出两份T对象的实例, 但是后续再次调⽤,就没有问题了,此时inst就不是空了,不能创建对象了。⼀般⽽⾔,多个线程并发同⼀段只有局部变量的代码时,不会出现不同的结果。

2025-04-02 14:10:37 807

原创 模拟实现线程池

我们今天就用threadpool类模拟线程池,线程池内部会有很多的线程,然后这个线程需要实现我们用户手动传入事务,所以内部肯定有一个事务队列,然后我们可以通过equeue函数传入各种不同的事务到队列中,这个队列是没有长度的,实际长度取决于我们传入多少事务,然后线程池内部的线程不可能杂乱无章,我们可以将其提前创建限定个数然后装进一个数组里面,我们称为线程数组,然后里面的线程依次竞争队列的资源,所以可以看出线程池就是一个生产者-消费者模型。如果使用endl等下报错会有一堆,不好看的,不必要在这里浪费时间。

2025-04-02 00:06:32 803

原创 POSIX信号量

上面申请信号量的过程称为P操作,释放信号量的过程称为V操作,进行P操作时进行申请资源,信号量值减1,如果信号量值 > 0,则减1并继续执行,如果信号量值 = 0,则进程/线程阻塞等待,进行V操作时释放资源,信号量值加1,说明此时信号量不为0可以被申请了,如果有进程/线程在等待该信号量,则唤醒一个,然后进行信号量值加1。信号量就是进行线程间同步的一个工具,信号量就是一个初始值为1的带锁的计数器,线程不断的申请信号量,当信号量是大于0的时候是可以申请成功的,申请成功就--为0,当信号量为0时就不可以进行申请。

2025-03-31 22:33:49 763

原创 日志与策略模式

我们这次选择在文件中和在显示器中进行落盘,打印函数统一为synclog,将选择在显示器和文件分别进行类的封装,在各自的类中实现这个打印函数,这边是两个类都在各自的类中实现这个函数,将来打印当前方式有很多难道都在自己的类中独立实现吗,所以我们选择构建刷新策略父类,将其弄成抽象类,将本次的刷新方法构建成一个纯虚函数,然后让我们的刷新到不同地方的类继承这个刷新策略的类,然后重写纯虚函数进而实现数据的刷新,一个日志的构成需要有1。需要有刷新落盘,就是显示位置,往哪里写入,2的默认位置和1的日志等级已经解决了。

2025-03-31 21:04:10 1589

原创 利用生产者-消费者理论实现阻塞队列的读写

由于我们上面这个是单生产者-单消费者的模式,如果改成多生产者-多消费者,当生产者生产速度远远大于消费者消费的速度那就会有少数的生产者线程在等待队列却受到了大量的生产者发来的解除等待的信号,那大量的signal进行唤醒肯定会容易出错,再加上某些系统(如 Linux)可能为了性能,允许线程在未收到信号时提前唤醒,多个线程竞争锁时,由于不符合加锁条件,而唤醒对立线程,大量的signal某些线程可能被错误唤醒,这种情况称为伪唤醒,pthread_cond_wait允许伪唤醒。有线程进入等待队列就++,唤醒就--。

2025-03-29 14:49:57 589

原创 条件变量与生产者-消费者模型

当一个线程抢到票时会加锁抢票过程,抢完了会进行解锁(交出锁的动作),但是此时它自己也属于了外面正在等待锁的线程呀,那线程A刚刚解锁又瞬间加入了抢夺锁的线程当中,如果这个线程A的优先级非常高那每次抢到锁的都是它,这样线程A每次都是加锁,解锁,再抢到锁,再解锁...,难道线程A做错了吗,没有,但是这么多线程都在等,就线程A一个在使用这个锁,如果线程A只是频繁的加锁解锁而没有在临界区干什么事的话(生产者线程向工厂一样会源源不断的向缓存写入数据,如同工厂源源不断的向超市进货一样的,生产者的生产数据是。

2025-03-28 19:59:29 1080

原创 对锁进行封装

我们还可以仿造RAII的形式对锁进行保护,加一个保护类,私有成员自然是这个锁了,然后将一个锁的加锁和解锁分别放在一个这个类的构造和析构函数里面,然后在while循环里面构造保护类的对象,此时由于由于保护类对象属于这个循环区域的,刚刚创建出来的时候会之间构造,调用保护类构造函数加锁之前会先调用我们之前那个代码构造锁,完成加锁,然后等出了循环自动释放调用析构函数解锁,并调用锁本身的析构函数释放锁资源,从而实现自动加锁+自动释放的RAII形式。我们今天学习对锁进行封装。makefile编写。

2025-03-27 10:50:01 528

原创 线程的同步与互斥

我们来学习线程的同步与互斥我们之前完成了对线程库的封装,本次会直接使用之前的代码。线程互斥几个概念临界区是每个线程内部访问临界资源的代码,注意临界区是代码片段,处于临界区内部的资源就是临界资源,多线程执行流共享的被保护的资源就叫做临界资源,就是多个线程都可以访问到的资源,并且这个资源要是被保护的才算,那被多个线程访问不被保护的资源就是共享资源。互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用。

2025-03-27 01:11:29 1021

原创 简易封装线程库

线程创建直接调用pthread_create方法,由于是传入了一个函数,我们可以直接将其填在第3个参数那里,但是我们使用另一个函数进行封装,在Routine里面进行调用,因为之前封装的函数调用是没有参数的,值得关注的是,这个Routine函数是成员函数,内涵this指针,所以我们只能将其设置成全局的或者友元函数,Routine的参数直接使用this就可以了。成功暂停完要将状态改成STOP,表示线程停止。主要是在我们自己的类里面进行创建线程,取消,退出,回收线程等的操作,并且设置线程属性。

2025-03-26 14:55:57 1228

原创 线程控制与线程库

对于Linux来说,其内核只有lwp,用户想要创建线程就需要调用用软件层封装的线程接口,那如果我们要得到线程的其他属性比如id,优先级,状态,栈大小,用户要调用线程库pthread.so就需要先将在用户内存的pthread.so线程库的地址通过页表映射到虚拟地址的共享区,在内存中线程库的内部维护着所有线程的属性集合,哦线程的属性存在这里,也就是线程的属性不是操作系统管理的,是线程库自己管理的,库管理线程属性集合依照先描述再组织的原则,对于比如线程大小,id状态什么的就装在一个struct结构体里面,

2025-03-25 23:45:41 783

原创 线程控制与线程操作

我们之前说过一般要调用线程创建函数,以pthread_开头的这些跟线程有关的函数都要在编译时指定线程库的,pthread_create这些函数不是系统调用是C语言封装的库函数,在Linux内核中没有线程的概念,只有LWP(轻量级进程的概念),线程是使用LWP进行模拟的,进一步来说Linux不会给我们提供线程的接口,只会提供轻量级进程的接口,轻量级进程和进程都是进程,怎么分呢,系统调用vfork巧妙的分出了进程。)中的一个函数,用于等待指定的线程终止,并获取该线程的返回值。用于主线程回收其创建的线程。

2025-03-24 00:26:02 870

原创 线程的概念和控制

我们今天学习线程的概念和控制虚拟地址转化物理地址。

2025-03-22 23:17:31 628

原创 线程的概念

操作系统需要管理内存,按照先描述再组织的原则,当有EIF格式的可执行程序运行时inode里面的数据和data block里面的数据都以数据块的形式存入内存,Linux中,内存管理的基本单位是4KB,所以每次存入的数据块都是4KB的,不够4KB的也存4KB,所以物理内存就是多个4KB的数据块的叠加,每个数据块又叫一个页,把物理内存按照⼀个固定的⻓度的⻚框进⾏分割,有时叫做物理⻚。⼀个⻚的⼤⼩等于⻚框的⼤⼩。可以循环的创建一堆的线程,注意是在同一个进程中创建的多个或者一个线程,所以根据上面的理论,

2025-03-21 22:48:22 1051

原创 与信号相关的其他知识

flag=1,没退出,但是当进入change方法,内存的flag的值改了,while理应再去内存拿flag然后更新到eax上,但是每次都去拿值修改很麻烦,并且主执行流并不知道flag改变了,所以编译器不知道flag变了,优化开启的时候就直接去eax里面拿值了,反正编译器误认为flag没有变,这样即使改变flag的值,while也只会拿CPU内部eax寄存器里始终不变的值,这不就错了吗?flag是不是等于0。切记不建议使用g++的优化进行测试flag值,因为C和C++的代码优化不一样,效果不一样,我试过。

2025-03-21 18:27:48 1035

原创 用户与内核---重谈地址空间

在极端情况下如果没有一个外设是准备好的,就是没有进程需要调度那操作系统不就闲置了吗,操作系统不太可能闲置,因为操作系统在创建/刚开始运行的时候会自己创建一些进程,这些属于操作系统自己弄的进程,然后这些进程可以负责对操作系统的各种缓冲区的进行刷新,操作系统自己创建的进程和用户创建的进程一样都是需要调度的,这种由操作系统自己创建的进程称为。,操作系统凭什么知道时钟(时间片)超时了呢,就是这种进程在检测的,所以操作系统也有自己的固定历程的,就算外设没有中断提供,内部也可以自己产生中断。操作系统的内核固定历程。

2025-03-21 00:22:50 799

原创 信号的捕捉(操作部分)

当handler方法正在被处理时,此时2号信号的pending表一定是1,但是如果假设handler处理时间很久并且有指令调用系统调用使CPU陷入内核,此时又来了很多个2号信号,OS不允许信号处理方法进行嵌套,当某个信号正在被处理时又来了这个信号,操作系统就不会将pending表其再置1了,转而将block表的对应位置1表示阻塞,等信息处理完自动解除阻塞状态。信号集是存储一组信号的集合,本质也是一个位图,信号集可以存储未决信号,屏蔽信号,所以信号屏蔽字是信号集的一种,我们可以自己创建一个信号集,其类型为。

2025-03-20 22:07:44 882

原创 自定义捕捉与处理信号的底层逻辑

信号的处理我们查询man 7 signal时看信号的具体退出行为时,一般是Core/Term,Term是信号正常退出不需要debug(调试),就是不给调试的机会,而以Core方式退出的信号会生成核心转储(core dumped),为什么我们系统报语法错误我们可以直接看到,这个错误信息就是OS从核心转储里面拿的,在进程崩溃的时候将进程在内存中的部分信息保存在当前目录下形成的pid.core文件,方便后续调试。

2025-03-18 23:13:53 1392

原创 信号产生和处理

进程内部有一张记录不同信号下标的位图,int整形32位,所以我们之前只关注了0-31的信号刚好存下整个位图,位图中比特位的位置是信号的编号,比特位对应的内容(二进制0/1),表示是否接收到对应的信号,所以发送信号的本质是写入信号,外设无论以什么方式发送信号,最终都是转换到OS,然后OS写入信号的,因为task_struct的唯一管理者是OS。信号是一种用户,OS,其他进程向目标发送异步事件的一种方式,操作系统·能识别信号是内置的,就是操作系统是知道信号的处理办法的,在信号产生之前就已经准备好了。

2025-03-18 01:06:38 929

原创 system V信号量

多个执行流(进程)能看到的同一份资源称为共享资源,被保护起来的资源加做临界资源,也就是说临界资源只允许在一个时间点有一个进程进行访问,所以我们保护的方式常见的是:互斥和同步,任何时刻只允许一个执行流访问资源叫做互斥,多个执行流访问临界资源的时候,具有一定的顺序性叫做同步,我们前面给共享内存加命名管道进行保护就是完美的解决了互斥和同步的问题。综合来看,System V IPC 更适用于需要高效、跨进程的通信,如共享内存提供最快速的进程间数据交换,消息队列适用于异步消息传递,而信号量用于进程同步和资源管理。

2025-03-15 20:01:27 530

原创 system V消息队列

我们发现msgtyp的传递就是和mtype相关的,这个在消息正文之上的mtype就是消息的编号,msgtyp可以通过传递不同的编号来读取不同的消息,依上图可知一般传递<0或者=0的数,因为。这个tm集合有时有月等等,很多的可以直接调用打印,但是要小心,这个tm_mon是1-11,所以用的时候要+1,year是减去1900的值,所以实际上要再加回来。它主要用于进程间的消息传递。如果是删除,buf结构体就不需要了,直接写成NULL,这个msqid_ds结构体就是存储的消息队列的内部信息的结构体,就是信息。

2025-03-15 13:34:52 807

原创 共享内存的通信

我们可以看到当我们只打开读端时,server并没有像管道那样没有东西可读就停止,而是直接读空,当clent以三秒一次写入时,读端确实读了,但是没有去重呀,可见共享内存的读取是不等写进程了自我独立运行的,是让两个进程各自共享用户空间内存块,当我们关闭读端时,写端还在写入,反之也是类似的,所以没有加任何保护机制,这个很危险的,这种让进程具有独立性的方法,容易让两进程数据不一致(一端还在写,一端已经读取了),我们就需要对共享内存自己完成保护,我们一般使用加锁,或者使用数据量保护处于临界区的临界资源。

2025-03-14 21:43:13 830

原创 共享内存的原理和创建

我们今天来学习共享内存!!!

2025-03-10 23:22:44 1078

原创 命名管道的创建和通信实现

mkfifo的第一个参数是创建管道的路径(包括文件名),第二个参数是管道的使用权限,返回值为0表示创建成功,-1表示失败,然后需要形成两个可执行程序,代表两个毫不相干的进程进行通信,然后编写makefile,同时编译两个进程。使用mkfifo创建了一个命名管道test,然后管道文件的标准就是后面有一个|,我们往里写入是不需要加|的,为了进行进程间的通信,我们需要再打开一个shell,然后有个shell进行写入,另一个看一下这个进程看能不能看到。,否则写操作会阻塞。这个不是系统函数,是C语言的内置函数,

2025-03-10 20:53:13 806

原创 标准错误流(stderr)与标准输出流(stdout)

所以我们为了让2的输入可以同步到log.txt里面,结果发现前面1已经默认同步了,这时只需要修改2的指向,让其指向1就可以了。这个现象可以看出输出重定向的前面肯定省略了输出重定向的文件描述符,输出重定向的本意肯定是想要让>前面的x文件描述符重定向到这个文件,使其步输入到显示器。我们今天运用标准错误流向显示器报显示错误,确实是直接显示出来了,但是下面当我们直接将此错误信息输入重定向到文件里面,结果文件里面什么都没有。我们这个是直接将2重定向到了这个文件,使其不再指向屏幕,我们也可以如下拆开的写法。

2025-03-09 16:47:59 266

原创 匿名管道运作的代码验证

我们可以看到,子进程写入管道到65536个字节后就不写了,65536 / 1024 = 64kb,所以我们当前的管道的容量就是64kb,但是之前配合有读出的父进程就不会使得子进程因为没有容量可写而卡住,因为读取操作会移除管道缓冲区中的数据,使后续的写入能够继续进行。那读入端都退出关闭了,管道写端正常并且写端关闭,那写端还在写的话肯定没有意义了,此时操作系统会直接杀掉写入的进程,OS会给目标进程发送kill的第13号信号SIGPIPE进行杀掉。具有血缘关系的进程可以进行IPC,常见于父子,爷孙也可以的。

2025-03-09 16:11:43 824

原创 进程间的通信1

父子进程同时来到管道两边进行通信,此时假设是父进程负责写入,子进程负责读取,管道的两端左边负责读取称为读端,右边就是写端,那父进程先创建管道,然后创建出子进程,为什么是先创建出管道再是子进程呢,因为子进程的fd是拷贝的父进程呀,先创建管道是为了能让子进程等下拷贝的时候负责读写的fd能和父进程指向同一个管道的两端。如果进行通信之前不关闭多余的端口会造成fd泄漏和进程的误操作,由于一开始设计时只需要单向通信,所以匿名管道这种技术就诞生了,这种管道不需要路径,不需要名字,只做单向的是为了需求。

2025-03-07 19:14:48 739

原创 EIF加载---虚拟物理地址加载

进行初始化的,所以当一个可执行程序加载到磁盘和物理内存时,一个进程来调度它,此时内核初始化了虚表,在物理内存里面的程序的内部使用虚拟地址,外部暴露出物理地址,当进行需要调度程序的某个指令时,其内的pc寄存器拿到暴露在外面的物理地址和可执行程序的路口,可执行程序只需要提供路口就可以了,然后页表根据这个物理地址形成映射,pc解析完指令,将指令的虚拟地址交给EIP寄存器,那CR3这个寄存器指向的是页表的映射关系,有帮助形成虚拟地址的功劳,既然要形成虚拟地址,所以CR3内部就肯定是物理地址了。

2025-03-05 22:24:52 584

原创 动态库与静态库2

努力肯定是没有白费的,毕竟这就是一种可行的方法的,系统在自动的情况下是不认识的,我们这时需要自己手动调用一下自己写的静态库,使用gcc的补充指令 -l+库名,我们的库名是libmystdio.a,不对太完整了,库名是去掉前缀的lib和后缀的.a然后剩下的就是库名了,如果要手动调用多个库名就需要添加多个-l,如-l+库名 -l+库名。,而不是完全静态编译的。在动态库底下的.conf结尾的配置文件,操作系统也是会在运行时访问的,我们就可以自己弄一个配置文件,然后将我们的库的地址存进去,就可以让操作系统看见了。

2025-03-05 10:27:55 1120

原创 动态库和静态库

如上图可以看出我们如果删除了原文件,那这个路径就消失了,所以对于只保存路径的软链接来说就失去了链接对象,但是之前我们看到了软连接里面的内容和原本的file.txt里面的是一样的,说明软连接的本质就是原文件,就是一个独立的文件,使用软连接就是在使用原文件,软链接是相对独立的,软链接有独立的inode,这种特性有点像windows的快捷方式。Linux下禁止了对目录的硬链接,这是为了放置目录自己形成回路,为什么软链可以,因为系统会自动略过软链接,反正只是存储路径,而且前面也讲过了,软链接不是真的链接了!

2025-03-04 20:51:25 684

原创 文件系统磁盘分区分组2

这样操作表,路径表,inode表就都完成了!左边是inode指针集,一般只有到三级指针,然后inode伸出指针指向block内容块,因为一个inode可以映射多个block,所以会先指向数据块的索引表,然后数据块的索引表伸出的指针就直接指向了block(数据块),这个结构的样子有点像跳表的,但两者完全不一样,为什么一个inode要映射这么多呢,多来几个inode分别映射数据块引索表中的数据不行吗,这是因为inode数量有限制的,不能太多了。分区必须经过"挂载"到目录上,分区才可以被用通过路径的方式访问!

2025-03-03 22:05:11 470

原创 操作系统的磁盘分区分组1

整个磁盘有很多扇区,如何管理这些扇区呢,OS和磁盘进行IO的时候,以扇区为基本单位,单次IO的数据量是很小的,所以外设很慢,只有4KB,所以扇区往往存在数据堆积的问题,此时磁盘将所有扇区分组,8个扇区为一组,每一组我们称为块,一个块就是8个LBA地址,块的编号从0开始依次增加,所以磁盘是以块为单位的一维数组。由于一个扇区是属于一个柱面的,所以我们必须先找到所属的柱面,然后再这个面上,一定会分布有很多位于不同层的磁头,然后找到对应的磁头,这样再根据磁头的指向查到扇区号。这现象只有机械硬盘HDD有,相比之下,

2025-03-03 19:34:15 1045

原创 模拟进程进行文件操作写入缓冲区的代码测试

不知道你们有没有发现fsync可以写在mfflush里面直接强制刷新,但是为什么不能写在外面,因为这个函数只能刷新系统内核的缓冲区,而外面自己制作的普通文件的缓冲区是不行的,那为什么写在里面可以,因为这行fsync的上面是系统调用write,调用了这个就已经写入系统的缓冲区了,而在外面没有写入的话,刷新了个寂寞呀!接着我们给每行写入都加上/n,那这样的话就真正实现了每行刷新了。本文就是对上一篇文章中所写的代码进行的测试,如下开始。测试文件main.c。

2025-03-01 00:27:59 200

原创 模拟进程通过系统调用向缓冲区写入并刷新的过程

C语言的创建文件函数本质在底层就是封装了系统调用的open,所以我们也只直接调用系统的open来创建,我们先判断传入的mode(文件执行方式),依照不同的执行方式进行创建不同使用权限的文件,然后返回一个fd,如果创建失败或者用户输入的mode不在比较范围那原有初始化的fd肯定不变(<0),就返回空了,在创建成功后,需要malloc一个FILE,初始化FILE里面的对象,我们再次默认刷新方式使用行刷新,最后返回值别忘了。是文件创建函数,像C语言的fopen一样,传入一个待文件的地址和文件要打开并执行的模式。

2025-02-28 22:57:13 557

python程序设计-图书管理系统(初级版)

python程序设计-图书管理系统(初级版)

2024-11-20

python程序设计-图书管理系统(初级版)

python程序设计-图书管理系统(初级版)

2024-11-20

空空如也

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

TA关注的人

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