- 博客(90)
- 收藏
- 关注
原创 【LINUX操作系统】通过System V看内核管理IPC资源
shmgetmsggetsemgetshmatshmdtmsgsndmsgrcvsemopshmctlIPC_RMIDmsgctlIPC_RMIDsemctlIPC_RMID我们一直强调“先描述、再组织”,现在来看一下这三种通信方式的组织结构是不是差不多。可以直接在机器上通过man xxxctl 查看!man shmctl共享内存对应属性的数据模块消息队列:信号量:例如其中的__key表示资源在系统中的编号,另外还有对应的uid表示持有当前资源的用户,三者除了有结构外,还有一些其他成员也基本类似。
2025-04-02 21:16:56
885
原创 初识linux(16) 动静态库(手搓动静态库!)
手搓动静态库,并学习如何使用自己的库,如何加载第三方库,以及加载时会遇到的问题。文章内容较长,全是干货。
2025-03-17 17:56:16
690
原创 初识Linux(14)Ext系列⽂件系统
之前谈论的都是已打开文件在操作系统的中的管理,但是还有更多的文件没有被打开,被存在磁盘中,如何管理这些磁盘中的文件,就是本篇的学习目标。
2025-03-14 17:52:23
690
1
原创 初识Linux(13) 由基础IO知识简易封装stdio.h中的FILE
fwrite的功能是将进程中的内容向语言缓冲区去写(拷贝),并且在需要刷新时执行刷新。memcpy的时候注意,要考虑缓冲区可能本来就有内容,所以要在数组的起始位置加上size。mfflush需要注意就是记得让size归零,因为刷新之后缓冲区应该再从0开始加入东西。本篇作为上文的拓展,可以锻炼一定的代码能力和进一步理清楚在系统中打开的文件的关系。两个.o文件可以直接链接起来。根据源码,以及上文的内容,FILE是由IO_FILE被typedef来的。每过一秒就cat一下log.txt,就能一行一行的获得内容。
2025-03-08 11:22:18
300
原创 初识Linux(12) 操作系统基础IO
所以大家可以想想,虽然显示器默认是行刷新,但是假如我们把每次打印的\n都给去掉,不会触发显示器的行刷新,就算不重定向,fork之后也会打印两次C语言库中的东西。都是硬件,C语言的这些接口,都是封装过的systemcall。在FILE中,C语言的接口封装了一个新的用户级缓存区,比如fwrite或者fputs之类的,在拷贝到内核缓冲区之前,先拷贝到用户级缓冲区。Linux下一切皆文件,以上三个流也先被当成文件给打开了(0,1,2),所以当我们再打开其他文件的时候,第一个返回的文件描述符就是3。
2025-03-06 10:46:11
649
原创 初识Linux(11):写一个自定义shell
shell (bash)的本质是一个进程,我们通过实现一个自主shell来贯通之前学的内容所有功能大概分成4部分:命令行是不断进行的,不会停止,以上四部分内容都要套在一个一直进行的循环中去。
2025-02-27 14:09:44
936
原创 初识Linux(10):进程管理
rid>0(wait与waitpid的返回值)只表示waitpid正常运行了,并不代表子进程成功退出了,子进程此时可能是异常退出的,不过僵尸进程已经被父进程给回收了。另外,进程⼀旦变成僵⼫状态,那就⼑枪不⼊,“杀⼈不眨眼”的kill -9 也⽆能为⼒,因为谁也没有办法杀死⼀个已经死去的进程。先说wait,wait能回收子进程的僵尸状态,因为如果子进程不退,父进程就会阻塞在wait函数内部。通常,⽗⼦代码共享,⽗⼦在不写⼊时,数据也是共享的,当任意⼀⽅试图写⼊,便以写时拷⻉的⽅式各⾃拷⼀份副本。
2025-02-22 15:53:37
986
原创 初识Linux(9):程序地址空间
实验结果:父子进程之间按理来说应该是写时拷贝,但是此时改变子进程的g_val的值,按理来说是拷贝到其他空间,但是打印出来的地址竟然是一样的。
2025-02-18 20:26:09
914
原创 初识Linux(8) :环境变量
main只是编写程序的接口,但不是第一个被操作系统调用的程序main函数之前还会有一个CRTstartup的函数,大概结构如下:
2025-02-11 14:17:51
890
原创 初始Linux(7):认识进程(下)
cpu资源分配的,就是指进程的优先权(priority优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能根本原因:每种设备的可用资源(磁盘/显示器/键盘..........)相比进程的数量还是太少了注意区分优先级和权限的概念,优先级是前与后的问题,权限是能不能的问题。
2025-02-02 01:30:23
763
原创 初识Linux(6):认识进程(中)
结合操作系统的进程状态,即:printf本质是通过system call去调用显示屏相关的驱动,但是输出是先输出到缓存区,再从缓存区输出到显示屏,在等待从缓存区输出到显示屏的过程中,该进程就会被调度到显示屏对应的task_struct* wait_queue中去等待。因此,跑起来就自动停止的程序,就算有内存泄漏,也问题不大。因为printf是与显示屏的交互,一直在做IO,IO是最花时间的,百分之九十九的时间都在IO,与显示屏进行交互,所以显式S+(s表示sleep,是一种休眠、阻塞的。
2025-01-23 15:52:26
783
原创 初识Linux(5) : 认识进程(上)
PCB是操作系统用于描述进程的当前状态以及控制进程运行的全部信息的数据结构。它是进程存在的唯一标志,记录了操作系统所需的,用于描述进程的当前情况以及控制进程运行的全部信息,如进程的状态、优先级、程序计数器、内存指针等。
2024-11-30 12:56:23
923
原创 初识Linux(4):Linux基础环境工具(下)
Git是一种版本控制系统,是一种工具,用于代码的存储和版本控制。而我们常见的Gitee和Gitehub都是基于Git(Git是开源的)实现的在线代码仓库,而前者服务器位于中国,后者服务器位于美国。
2024-11-27 17:31:51
928
原创 C++ unordered封装
哈希表是unordered系列容器的底层逻辑,再实现了哈希的底层后,我们按照如下步骤封装unordered:1. 改变数据类型,将HashTable中的所有的_kv都改成T2. 因为map需要取key,写一个KeyOfT的仿函数并封装3. iterator , ConstIterator的实现和封装4. 解决set和map中的key不能修改(value应该设计成可以修改)依照上述思路,我们来实现代码。
2024-11-04 18:37:53
976
原创 初始Linux (2) : 权限
Linux中有两种用户:普通用户、超级用户超级用户可以再linux系统下做任何事情,不受限制;而普通用户只能做有限的事情。可以使用指令:su -快速进入root账户,但需要输入相关密码。超级用户可以直接切换到任意普通用户,不需要输入密码:普通用户的命令行提示是$超级用户的命令行提示是#如果不想变成root,但是想用root的权限做事(sudo):sudo指令在配置进配置文件之前是不能被执行的:必须将用户lsnm添加到配置文件中,lsnm才能使用sudo命令。
2024-11-01 01:29:34
1080
原创 初识Linux(1):基础指令
Linux是一种自由和开放源代码的类UNIX操作系统,该操作系统的内核由林纳斯托瓦兹在1991年首次发布,之后,在加上用户空间的应用程序之后,就成为了Linux操作系统。严格来讲,Linux只是操作系统内核本身,但通常采用“Linux内核来表达该意思。而Linux则常用来指基于Linux内核的完整操作系统,它包括GUI组件和许多其他实用工具。Linux是由赫尔辛基的一名研究生Linus开发的。
2024-10-30 15:18:03
1293
原创 C++ 基于自主实现的红黑树封装Map和Set (上)
经过改造的红黑树只需要处理一个T类型的data , 至于T是什么我们不再纠结。但是为了便于比较大小,set需要有set获得key的方法,map需要map获得key的方法,因此还需向红黑树里传一个仿函数。最后就是迭代器的实现,先将iterator写成一个类,再依次封装进tree和两个容器中去。
2024-10-18 15:59:20
809
原创 C++ 红黑树
因为红色不能连续,所以:最短情况:全黑并且因为LogN足够小所以对cpu的运算速度来说,LogN和2*LogN没区别。因此可以认为红黑树与AVL树的效率是差距不大的。反而在插入和删除元素时红黑树更有优势,调整起来没有那么麻烦。2. 红黑树的插入以此树为例: 这个情况下要添加节点,加红节点还是黑节点呢?无论怎样加都会破坏规则。具体调整分析如下:红黑树的调整中,多通过观察三代:子cur 父parent 叔叔uncl
2024-10-17 12:28:22
1120
原创 C++ AVLTree
目录1. AVLTree的定义2. 平衡因子3. AVLTree的基础接口 插入 旋转左单旋:右单旋:双旋:4. AVLTree的测试 5. 小结以下树为例进行分析。 将平衡因子当作一个风向标。标出每一个节点现在的平衡因子: 下面来讨论在普遍情况下插入节点后平衡因子的变化。基本结构都和二叉搜索树类似。先实现结点:再写树:构造我们现在只强调一下拷贝构造。
2024-10-12 14:17:58
856
原创 C++ STL初阶(14): map和set
之前我们学习的线性的容器,如:vector deque list等都叫作与之对立的概念是也是用来存储数据的,与序列式容器不同的是,其。key就是键值,可以在容器中通过键值直接找到value.比如:现在要建立一个英汉互译的字典,那该字典中必然 有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应 该单词,在词典中就可以找到与其对应的中文含义我们在 前导文章中的代码的基础上继续往下写:在搜索二叉树中,有两种典型的模型:key模型和key_value模型。
2024-09-27 19:21:11
806
原创 C++ :借助栈完成二叉树的非递归遍历
1. 前序遍历二叉树的传统访问分为:前序、中序、后序、层序。其中前三者是递归访问,但是递归是有缺陷的,树太深就会栈溢出。因此本文我们思考如何使用非递归的方法来完成遍历。1. 前序遍历要迭代⾮递归实现⼆叉树前序遍历,⾸先还是要借助递归的类似的思想,只是需要把结点存在栈中。
2024-09-24 18:01:10
847
原创 <刷题笔记> 力扣105/106题 使用中序+前(后)序构造二叉树
这是一个只需要前序就能构造二叉树的题,因为一旦遇到空,就有"#"作为返回的标志,能够立刻返回。
2024-09-23 14:37:28
800
原创 <刷题笔记> 力扣236题——二叉树的公共祖先
236. 二叉树的最近公共祖先 - 力扣(LeetCode) 题目解释:我们以这棵树为例,来观察找不同的最近公共祖先有何特点:先来特殊处理第二种情况:然后涉及到最关键的步骤:实现IsInTree:完整代码:但是实际运行速度并不理想: 运行速度几乎都要接近一秒了这样操作的时间复杂度是O(N^2): 使用前序查找+栈来找记录路径,然后再进行一次“
2024-09-22 16:58:52
638
原创 C++ 二叉树进阶
或者是具有以下性质的二叉树所有节点的值都小于根节点的值所有节点的值都大于根节点的值并且二叉搜索树的中序遍历之后是一个有序数组,就是因为先走左边的,但是左边的一定更小;最后再右边的,但是右边的一定最大。二叉搜索树也叫BinarySearchTree 即 BST二叉搜索树的功能:在C语言阶段对树的学习中我们了解到,二叉树用于储存数据或者用于排序并非最优解。二叉树的主要功能是查找:理论上,二叉搜索树中不允许有冗余、重复的数据(这里一个4、那里一个4)
2024-09-12 12:33:30
689
原创 C++ 多态学习笔记(下)
开始新的学习之前,我们先通过一段涉及继承、多态的 代码来回忆、加深理解。Animal作为基类,我们要给每种动物实例化出sound()的模块,因为Animal在实际意义上没什么好实例化的,所以设计成抽象类。虽然Animal不能实例化出对象,,来作为的条件。这里的Animal就是作为一个像工具人一样的类,本身就不打算实例一个Animal,因为必须要指定出具体是什么动物之后,sound()这个函数才有意义。
2024-09-09 17:13:32
1176
原创 C++多态 学习笔记(上)
此时表示Student的BuyTicket不能被继承。如果在Person的buyticket后面加final,就会语法报错final还能用于修饰类,final修饰的类不能被继承。或者还有没有办法能使一个类不能被继承?将基类函数的构造函数写成private,也能间接使该基类不能被继承。
2024-09-06 13:47:37
1011
原创 C++ 继承学习笔记
同一个域是不能有同名变量的,但是基类和派生类作为两个域,是可以有重名变量的。子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问根据查找规则也可以理解,要先去找 自己的类域里面找,找不到再去父类的类域。这种操作被叫做重定义或者隐藏。来看两个关于隐藏的题目:第一题:答案是B两者构成隐藏。重载要求在同一个作用域。如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
2024-09-05 15:02:28
1193
原创 C++ 模版进阶
不过在C++20之后就支持double和指针等内置类型作为非类型模版参数,但是依然不支持如string等非内置类型。并且传进来的这个N是常量,是不会被修改的。关于非类型模版参数的运用,很多场景还是用于定义一个新的数组。再看看c++标准库中非类型模版参数的运用:C++11中加入了一个array类(用类封装的静态数组),其中就使用到了非类型模版参数使用:那么array有什么优势呢?在C语言中,由int a[10]这样定义出的数组中,对于越界的检查是采取的:先设置标志位随机抽查。
2024-09-02 16:23:39
1175
原创 C++STL初阶(13):双端队列deque和优先级队列priority_queue(包含详细计算)、仿函数介绍
双开口的含义是:可以在头尾两端进行插入和 删除操作,且时间复杂度为O(1),与vector比较,头插效率高,不需要搬移元素;与list比较,空间利用率比较高。尽管名字叫双端队列,但是deque和队列FIFO的特性没有太多关系,我们抛开先进先出的特性进行学习。deque是一个顺序容器(sequence container),而不是容器适配器。
2024-08-20 15:01:17
1207
原创 C++STL初阶(12):stack和queue的初阶实现
top表示下标,_capacity表示空间大小:那么按照我们原来的思路,利用_top和_capacity T*来给stack构形。如果只是按照c语言的思路来实现一个T*的多接口数组就显得有些重复了。
2024-08-17 13:33:05
1022
原创 C++STL初阶(11):stack和queue的使用
使用一个变量levelSize而非队列来控制一层一层出:(本质和思路一差不多,思路一相当于是给每一个数据做记号,记录该结点是哪一层的,思路二则是使用一个数据整体记录。接着再来看红箭头指的1和左栈最上面的1:换句话说,当入栈的元素和最小值是一样的时候,是否在小栈里面也应该再入一个1呢?函数名的push和_st.push()中的push不是同一个,后面是库中的push,第一个是我们自己实现的push。该底层容器应至少支持以下操。此时出栈的逻辑就会复杂一点,当左栈的元素大于小栈时,只出左栈即可,右栈不动就行。
2024-08-15 18:25:59
755
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人