- 博客(93)
- 收藏
- 关注
原创 关于mmap的理解和使用
本篇文章介绍的是mmap的经典用法——文件映射,mmap允许用户将文件或设备的内容(文件内核缓冲区)直接映射到用户的虚拟地址空间中,用户通过虚拟地址直接访问文件缓冲区,避免了read/write等系统调用带来的拷贝和性能开销。共享内存和动态库的加载。
2026-03-24 17:20:58
202
原创 OS中的文件
我们不仅可以把磁盘看做文件,还可以把其他外设例如:键盘,显示器都看做文件,对它们的操作看做对文件的读写操作。这种屏蔽底层差异,使上层统一的封装也就是是C语言的多态。struct_file结构体。linux下一切皆文件。
2026-03-23 09:49:56
460
原创 OS进程管理
因此只要我们让两份进程存放返回值的虚拟地址映射的实际内存不同既可以实现返回不同的值。也就是说在返回之前让他两返回的同一个变量的数据不同。具体来说:代码同一份(代码是只读的,不影响独立性),数据不相同。因为我们不一定是直接赋值,还可能是x++这种基于原来值的修改。为什么不直接修改PR,而是通过修改NI间接修改优先级?为什么写时拷贝还要把原数据拷贝一份,反正还要修改?为什么对于父子进程返回的id不是相同的?进程地址空间(虚拟地址空间)子进程继承父进程地址空间?为什么要有虚拟内存+页表?虚拟地址空间如何初始化?
2026-03-22 19:49:19
336
原创 sizeof和strlen的区分
从目的上来讲,sizeof所求的是变量或者数据类型的内存空间的占用量(包括‘/0’),单位是字节。而strlen求的是字符串的大小(不包括‘/0’),单位是字符。从性质上来讲,sizeof是一个关键字,而strlen是一个函数,它们两个一个是编译时期就确认的,另一个则是运行时得到结果。
2026-03-17 16:49:45
18
原创 Qt-qrc机制简单介绍
注:不仅是图片,音频文件等也可以利用qrc机制,包括我们的qss样式表的代码与样式分离也可以利用qss机制,这在Qss一节中有介绍。好,接下来我们捋顺一下qrc机制的思路。
2026-02-08 19:56:58
461
原创 Qt——线程
类似于linux中的pthread线程库,c++中的线程库,Qt也封装了线程。linux和c++中的线程库是通过函数指针来给线程指定要执行的逻辑,而Qt是通过重写QThread的run方法。客户端使用单线程处理事件,防止占用太多用户PC资源,所以一旦有长时间任务意味着客户端要停止响应用户较长时间。不同于服务器(使用线程是为了更快处理,更好利用资源),客户端中的线程是为了良好的用户体验,比如将一些耗时的文件上传和下载任务交给子线程,这样客户端的主线程还能正常响应用户。这里使用线程实现倒计时。
2026-02-07 18:21:01
238
原创 Qt——事件简单介绍
如果想对某控件的某些事件做出处理,就使用继承自该控件的子类控件并重写父类控件中对应事件的虚函数。即创建继承自Qt内置控件类的新控件类并重写其事件处理函数。题外话——setMouseTracking(true),我们使用新的控件类自然就绑定了新的事件处理函数。题外话——自定义类如何使用QtDesigner。重写Qt内置控件的事件处理函数。事件和处理函数的关联。
2026-02-07 12:38:17
657
原创 Qt——QDialog
上面我们使用Qt内置的按钮,但是怎么辨别用户点了那个按钮并做相应处理,一般来说我们使用信号槽,但是。通过show或者exec的返回值我们就可以或者用户点击了那个Qt内置按钮。Qt内置的按钮是Qt自己生成的,我们无法获知信号源和具体信号。
2026-02-06 17:52:15
970
原创 QT——QMainWindow
细心的同学可能发现我在创建菜单栏的时候没有指定菜单栏的父对象可能导致内存泄漏,不必担心,setMenuBar会帮我们把对象挂到对象树上。添加菜单栏,添加菜单,添加菜单项,并为菜单项设置触发事件(槽函数)题外话——创建菜单栏的内存泄漏。状态栏(Status Bar)
2026-02-06 12:20:21
1004
原创 Qt——常用控件
QLCDNumber中有value (double类型)和 intValue两个属性表示值,且他们是联动的,比如value为1.5,inValue就为2。QlineEdit中的inputMask元素上面我们已经使用过了,但是他只能进行简单的验证,正则表达式验证才是经常被使用的输入框数据验证方法。,QApplication对象在main函数调用exec函数后,主线程开始时间循环,依此处理对界面的修改任务。QTabWidget里包含的是若干个QWidget控件,相当于若干个新的窗口。
2026-02-05 20:44:37
1708
原创 Qt——信号槽
顺便提一下,以前connect函数的第二和第四个参数都是char*类型的,因此每次传参都要把实参用宏强转成char*,但是现在重载了更好用的版本。关联信号和槽有多种方式,我们下面逐一介绍。Connect函数方式。信号和槽(slot)
2026-02-02 15:22:47
591
原创 简单介绍Cookie和Session
问题:由于HTTP协议的无状态性,导致用户体验变差(比如每换一个页面就重新登录),也阻止了用户与服务器交互(比如记录购物车里的商品)。
2026-01-22 18:10:30
51
原创 谈谈IO模型以及效率问题
如果使用的是信号驱动IO,就把这个回调函数指向信号发送函数,这样一有事件就绪,就会自动通过回调函数发送SIGIO给对应进程,进程执行信号处理函数,而这个信号处理函数早已经被我们设置为执行读取或写入的代码了,这就是信号驱动IO的原理!但我们这里关注点并不在计算机,而是在于提供服务的程序,或者直白来说,进程的IO效率如何,这是评价客户端/服务器架构的程序好坏的标准之一。我们这里只是介绍一下select的使用,所以服务器使用面向过程的方式编写,并且我们也只使用了readfds,后面会编写一个完整的服务器。
2026-01-20 10:06:03
832
原创 OS中的线程
上面我们说过,linux没有专门的线程机制,所以也就没有用于创建,管理线程的接口,但是linux之前用来对进程控制的系统调用具有较好的扩展性,所以可以使用这些系统调用模拟出线程体系,计算机内有很多进程,所有进程引用同一个线程库,进程由很多线程组成,因此线程库管理着所有线程。就是做这个的,所以下面介绍的函数都不是系统调用,而是由我们链接的用户级线程库提供的。进程是资源分配的基本单元,而线程是系统调度的基本单元,一个进程包含若干个线程。总的来说,主线程做的步骤是,创建子线程,等待回收子线程/分离子线程。
2026-01-16 12:47:37
721
原创 深刻理解动静态库
要知道,如果我们的代码中使用到了静态库中的函数,那么main文件就需要和静态库进行连接,而静态库有很多,因此,在制作完成静态库之后,我们利用静态库编译main文件的时候,也要让编译器知道要链接的库在哪儿。当然,虚拟地址空间中也有分区,即规定,那一片区域是被用来分配给谁,所以每个vm_area_struct都属于其中一个分区,而映射动态库的vm_area_struct属于共享区。第一部分安装是为了让编译器利用动态库编译main文件的时候能找到动态库的位置,这一点和静态库的安装完全一致,下面我们就不再多说。
2026-01-15 11:43:54
612
原创 linux软硬链接
通过软链接文件,可以快速访问到深路径下的文件,常常作为一种快捷方式。通过硬链接文件,可以用很低的成本做文件备份。需要注意的是,硬链接不能链接目录。使用软链接链接目录为什么是可以的。
2026-01-04 10:03:54
336
原创 深刻理解文件系统(linux和EXT*为例)
首先明白,管理文件和磁盘确实是OS的任务,但是管理文件和磁盘的管理信息是要保存到磁盘上去的,因为每次重启后内存中的数据都不会保存(不可能说,一旦重启,OS就把之前的文件存在哪儿都忘记了)。然而,如果OS内使用CHS方式寻址磁盘,那么兼容性是很不好的,因为我们知道,外部存储设备不止是磁盘,还有硬盘,未来还会有新的存储设备,而这些存储设备不见得都有柱面、磁头、扇区,那么就要不断修改OS的代码。以上所述的都是一些对磁盘访问的知识。磁盘只是存储介质,它本身没有管理自己空间的功能,更没有管理存储在其中的文件的功能。
2026-01-03 08:58:46
873
原创 深刻理解函数调用过程
但是,跳转到目标函数并执行指令后如何返回调用者的位置继续执行调用者函数剩余的指令?最主要的问题是,在执行程序的整个过程中怎么区分局部变量等栈上的数据是属于那个函数的?对于代码中的函数调用来说,会被翻译为跳转指令(跳转到存放目标函数的指令区域)。如果在调用函数之前寄存器有值,那么调用者会把寄存器的值保存在自己的函数栈里,等到调用结束,调用者就读取他们以恢复寄存器的值。被调用者通过ebp-n来访问调用者传给它的参数,函数的返回值通过寄存器返回给调用者。,至于调用栈如何工作,是我们这篇文章讨论的。
2025-12-23 08:58:31
499
原创 互斥和同步(生产者消费者模型)
注:该类型的生产者消费者模型将缓冲区当作局部使用(但也不是完全局部,至少没有实现生产者之间的并发(并行)放入,只实现了生产者和消费者之间的并发(并行)访问)。被挂起的执行流的PCB/TCB会被放到内核中的某等待队列中,并且PCB/TCB的状态会被修改为睡眠,所以本执行流不再被调度。对条件变量进一步的叙述需要结合接口的使用来进行,所以在这里先来介绍一下条件变量接口的使用,希望读者不要感到突兀。当然,互斥的实现方式多种多样,比如中断屏蔽,比如OS提供的原子操作接口,而我给读者介绍的只是其中一种——互斥锁。
2025-12-19 15:24:41
766
原创 网络层次划分—深入理解传输层
拥塞控制并不是单纯的提高网络承受上限的问题,比如说,当我们发现由于路由器缓存不足而导致网络拥塞,如果直接把路由器缓存扩大,那么也不能解决问题,因为太多的数据包在路由器缓存队列中排队,发送发迟迟收不到确认也会触发超时重传,结果就是发送更多的数据包,导致路由器缓存中的队列更长,还是会拥塞。在发送端,滑动窗口前面的数据是已经发送了并且收到确认的数据,滑动窗口后面是不能发送的数据(可能由于没有数据要发送,可能由于B的可接收的数据量的限制),而滑动窗口内部则是可发送但是未发送的包括已发送但未确认的数据。
2025-11-28 18:14:10
1152
原创 网络层次划分-网络层
两相对比之下,第二种方式承认了通信的不可靠性,而让通信双方维护可靠性。使用第二种方式部署网络造价大大降低,而且使得网络运行方式灵活(第一种方式要预留出线路资源)。而计算机上层具有很强的处理能力,就算出错了也能有效处理,因此第二种方式就比较适合了。,它总是路由项目表中的第一位,不难看出,这个地址块的地址掩码是全1,也就是说任何目的IP和它按位与都等于目的IP本身,这可以为发往特定的目的地址的数据包开辟一个专用的接口,即把目标网络设置为想要使用专用接口的目的IP,地址掩码是全1,接口设置为专用接口的名字)。
2025-10-16 18:46:11
1134
原创 网络层次划分-数据链路层
这样的话帧定界作用就会消失,帧会被胡乱截断,导致的结果就是,帧包裹的IP数据报也四分五裂了,即IP数据报看到了干扰,而且这可不是重传能解决的问题,因为再次发送,IP数据报的内容也不能变。简单讲这个协议做的事情,就是让网卡不断进行碰撞检测:当两个站点同时发出信息时,总线上的信号电压变化幅度会变大,而网卡一但检测到这个幅度超出了一定的门限值,就认为在发送消息的过程中发生了碰撞,并停止继续发送消息,等待一段时间。限制帧的最小长度,如果帧太小,就填充字节进去(因此,帧长度不仅有最大值,也有最小值)
2025-10-02 15:13:50
572
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅