
Linux系统编程
文章平均质量分 69
学习Liunx内核
W2155
这个作者很懒,什么都没留下…
展开
-
LINUX系统编程:信号(1)
Linux让系统提供让用户给其他进程异步发送消息的一种方式。站在进程的角度看待信号1.信号在没被发送之前,进程是认识这个信号。2.在接受到信号之后,进程是被设定好去怎么处理这个信号的。3.信号到来的时候,如果进程有更重要的事情要做,这个信号会被临时保存。4.收到信号之后可以不立即处理,等到机会合适在处理信号。5.信号产生是不定时,随时都可能接受到信号,所以信号是异步发送的,是别的用户和进程。原创 2024-06-03 22:18:41 · 1331 阅读 · 0 评论 -
LINUX系统编程:进程间通信之共享内存
ftok使用参数pathname和最少8个有效位的参数proj_id(必须不为0)生成一个key_t类型的System V IPC密钥,适用于msgget,semget,shmget这三个函数。size:就是开辟多大的共享内存,共享内存的开辟是以4kb为单位的,size的大小建议设置4*n,因为即使size为7,还是会开辟8个字节的内存,剩下的一个字节就浪费了。进程间通信的本质就是让进程看到同一块系统提供的资源,共享内存就是让不同进程看到同一块内存,用内存作为媒介,让两个不同进程通信。原创 2024-05-30 19:31:06 · 546 阅读 · 0 评论 -
LINUX系统编程:基于阻塞队列的生产者消费者模型
它是时一个经典的多线程并发的协作模型,也就是生产者(线程)向一个公共区域(阻塞队列)生产,生产出的“商品”被消费者(线程)消费。其中生产者可以拥有多个,消费者可以拥有多个,但是公共区域只有一个。原创 2024-07-12 10:17:54 · 842 阅读 · 0 评论 -
LIUNX系统编程:进程池的实现
每一个可执行程序,在被执行前都要转化为进程,操作系统都要为其创建PCB,地址空间,页表,构建映射关系,进程池就是创建进程时,创建很多个进程,如果要执行程序,就直接使用创建好的进程。就像一次性创建5个进程,肯定是比一次创建一个创建5次的效率更好的,将任务均匀的分配给进程执行。原创 2024-05-06 20:23:47 · 513 阅读 · 0 评论 -
LINUX系统编程:信号(2)
当进程收到2信号,首先会将pending位图第二比特位变为1,等到机会合适时处理pending中的信号,处理时会看2号信号的位置在block中是否为1,如果为1就阻塞住,不递达,为0就递达,调用handler中对应的函数。它们也是不可阻塞的,因为它们是用来控制进程执行状态的信号,不受进程阻塞的影响。3.向进程发送2号信号,因为2号信号被阻塞了,所以2号信号会一直在pending位图中。处理信号的动作叫做递达(Delivery),处理信号有三种方式,默认,忽略,自定义。原创 2024-06-06 11:26:12 · 625 阅读 · 0 评论 -
LINUX系统编程:原生线程库的封装
在c++11之后,c++也支持了多线程,也就是thread库,thread库一定是对pthread库的一个封装,因为在Linux下不存在线程的概念,只有轻量级进程,pthread库就是对轻量级进程的系统调用接口封装成线程接口。那么对线程的管理一定不是操作系统做的,因为操作系统不认识线程,这个工作是由pthread原生线程库做的。pthread动态链接到共享区,使用struct pthread描述线程,struct pthread在共享区的起始地址就是该线程的 tid。可以打印看看sleep(1);原创 2024-06-30 14:54:28 · 786 阅读 · 0 评论 -
LINUX系统编程:基于环形队列和信号量的生产者消费者模型
当下标遍历到vector末尾的时候, 下标 %=判断环形队列为空还是为满 vector容量,下标就回到数组的开始。所以生产者在生产之前要对空间的信号量进行p操作,生产完成之后要对数据的信号量进行v操作。所以消费者在生产之前要对数据的信号量进行p操作,消费完成之后要对空间的信号量进行v操作。队列一定不为空&&不为满,这个时候生产者可以生产,消费者可以消费。环形队列可以实现并发生产和消费,就是在消费的同时也可以生产。为空的时,只能让生产者先生产,消费者后消费,为满时,消费者先消费,生产者后生产。原创 2024-07-12 22:55:39 · 716 阅读 · 0 评论 -
LINUX系统编程:线程的概念
本文主要介绍,在LIUNX下的线程。原创 2024-06-20 09:54:39 · 367 阅读 · 0 评论 -
LINUX系统编程:信号量
信号量可以在多执行流下对,共享资源进行保护(例:共享内存本身是是一种共享资源,但是本身是不带协同机制的,这样就会出现数据不一致的问题,写端想写"hello world",但是在写端写到hello时,读端就把数据读走了,造成了数据不一致)。每个小区域都有自己的编号,当一个执行流想使用小块资源时必须,申请对应的编号,然后才能让问对应的小区域,使用完之后还要将编号还回去,这样保证每一块的小资源都是互斥访问的,大块的资源就是多个进程同步访问的。信号量是一种资源预定机制,只要预定了,资源在未来一定是该进程的。原创 2024-06-03 11:12:13 · 690 阅读 · 0 评论 -
LIUNX系统编程:可重入函数&&volatile
在执行流执行到mian函数,insert函数中的1号位置的时候,突然就陷入内核,处理信号,执行信号自定义方法,这个方法调用的也是insert,执行完之后,导致了n2的节点丢失,那么这个函数就叫不可重入函数,如果在执行流重复进入的情况下不会出问题的就叫,可重入函数。我们发现已经终止不了,这是因为编译器看我们的main函数中没有对flag的修改,直接就把flag放到寄存器中了,省着还要和内存交互,但是我们对内存的flag修改,并不会影响寄存器。这个关键字主要就是防止编译器的优化,保持内存的可见性。原创 2024-06-12 22:07:11 · 265 阅读 · 0 评论 -
LINUX系统编程:多线程互斥
这也就解释了,为什票会抢到负数,究其原因就是我们抢票+判断的操作不是原子的,所以我们要通过互斥锁把这两个操作编程"原子"的,这个原子是在线程看来是原子的,不是真正意义上的原子。thread1开始执行,thread1进行判断,thread1发现票数也是大于0的,进入循环,这个时候hread1的时间片到了,thread1进入等待队列。thread0进行判断,thread0发现票数是大于0的,他就会进入循环,但是这个时候thread0的时间片到了,thread0进入等待队列。3.销毁的互斥量,就不要在加锁了。原创 2024-06-30 19:55:47 · 839 阅读 · 0 评论 -
LIUNX系统编程:进程间通信-管道(2)
说明代码会把管道的数据读完,然后读到文件末尾,结束读取。说明读端关闭,os会终止写进程,使用信号13杀死写进程。同上,什么也读不出来,管道写满,写端阻塞等待。什么也没读出来,说明读端一直在阻塞等待。子进程的退出信号是13,原创 2024-05-03 21:59:55 · 262 阅读 · 0 评论 -
LINUX:懒汉单例模式线程池
创建一个线程,就是要这个线程去完成某种任务的。池化技术就是,提前创建一批线程,有任务这一批线程就会执行。而不是有任务的时候在去创建线程。池化技术有着更高的效率,因为线程都是提前创建好的,直接执行任务。原创 2024-07-16 12:57:18 · 604 阅读 · 0 评论 -
LINUX系统编程:核心转储
Core终止,在终止之后会生成,一个core文件,将进程在内存中的内核数据(与调试有关)转储到磁盘当中形成core文件,然后将进程干掉。在使用信号的时候,我们发现大多数的信号都是终止进程,虽然都是终止进程,但是终止进程是有两种方式的。我们发现core文件默认的最大大小是0,我们只需要将core文件最大大小修改一下,确保能够捕获足够的信息用于调试即可。如果每次启动就挂掉,会一直重启,一直挂掉,会生成很多的core文件,最后磁盘被打满,整个系统就挂了。当一个服务挂了,第一肯定是先恢复服务,然后在去解决问题。原创 2024-06-05 20:38:58 · 462 阅读 · 0 评论 -
LIUNX系统编程:信号(3)
内核级的页表只有一份,因为操作系统只有一个,操作系统的内核数据也只有一份,只需要一个内核级的页表,建立不同进程的虚拟地址到操作系统所处物理内存的映射,就可以让多个进程看到一个操作系统。硬件中断:键盘直接连接到cpu的针脚上,当键盘输入的时候,会给对应的针脚一个高电频,cpu会拿着这个针脚的编号,去操作系统的中断向量表(函数指针数组),执行对应的函数。由一个硬件,向操作系统发送一个频率非常高,时间非常短的周期时钟中断,操作系统会拿着中断号去操作系统的中断向量表中,执行进程调度,内存管理,更新系统时间。原创 2024-06-07 21:22:23 · 760 阅读 · 0 评论 -
LINUX系统编程:线程控制
但是别忘了还有缓存命中这种东西,cpu在加载代码的时候,会把该代码附近几行也加载到cpu的高速缓存中,一旦进程切换了,这些高速缓存的数据,对于下个进程就没有用了,都是失效的数据,但是对线程不是这样的,线程代码和全局数据是共享的。在LINUX内核中是不存在线程的概念的,只有轻量级进程的概念,但是在用户的角度来看,用户就是要把轻量级进程当做线程的使用,所以将轻量级进程的控制接口,封装成了一个线程库,用户直接使用库,也就屏蔽了底层的实现。2.操作系统切换线程的工作,要比进程小的很多。原创 2024-06-21 16:58:17 · 906 阅读 · 0 评论 -
LINUX系统编程:命名管道
匿名管道的通信只能在,有血缘关系的进程中,本质就是,子进程会拷贝一份父进程的文件描述符表,父子进程就可以看到操作系统的同一块资源(文件),以这块资源为媒介进行通信。命名管道,就是以路径为标识符,让两个不相干的进程,看到同一块资源(文件),以这个文件进行通信。原创 2024-05-24 20:48:47 · 603 阅读 · 0 评论 -
LIUNX系统编程:动态库加载(2)
虚拟地址空间并不是有操作系统一个完成的,而是需要cpu,编译器,操作系统,三者共同联动,互相配合,编译器在编译的时候就已经生成虚拟地址了,CPU的MMU + 操作系统的页表才能讲虚拟的地址转化为物理地址。使用绝对编址的方式,对每个指令,进行编址,然后将链接了哪些动态库,main函数的地址(虚拟地址),代码区,数据区,已初始化的数据.....各个区域的大小划分,存储到到表头中。当指令寄存器,执行指令的时候,需要访问物理地址,这是时候cpu会给MMU一个请求,MMU区页表中查询,将虚拟的地址转化为物理地址。原创 2024-04-29 11:52:34 · 419 阅读 · 0 评论 -
LINUX系统编程:动静态库的制作
gcc -o main mian.c -L./ -lmymath //库的名字是去掉前缀和后缀的libmymath.a mymath。例:我写了一个函数,我想让别人使用,但是并不像让使用者看到我写的代码,就可以把我的代码制作成一个库,提供给使用者。ar -rc libmymath.a add.o sub.o//-rc(crate和replace)将add.c sub.c add.h sub.h 制作成静态库。1.首先要将add.c sub.c编译生成.o文件。使用-L选项制定库的路径,-l指定库的名称。原创 2024-04-26 20:42:24 · 230 阅读 · 0 评论 -
LINUX系统编程:软硬链接,动静态连接
什么是硬连接?,我们或许可以用操作清楚的认识什么是硬连接。在我们学习文件的时候这个数字好像完全没有被提到过,这个代表什么意思呢?这个代表该文件的inode编号与文件映射的次数,现在该文件的inode只与test.c这个文件名映射,所以该数字为1,这时候使用ln命令,给该文件建立一个硬连接文件。ln test.c test.a//为test.c建立名为test.a的硬连接看这两个文件的标号变为2,说明这两个文件使用的是一个inode编号,inode的编号一样说明他们本质上是一个文件。原创 2024-04-26 19:47:45 · 500 阅读 · 0 评论 -
LIUNX系统编程:文件系统
在用户使用LIUNX系统的时候,我们查找一个文件用的都是路径去查找,但是想找到一个磁盘的文件,必须找到该文件的inode,怎么用一个路径,就找到文件的inode的呢?依次类推,直到根目录,根目录的inode编号是确定的,系统是直接知道的,开机的时候,就会用这个编号,将根目录打开到内存当中,根目录的inode编号是2。想找到test.c,就必须找到先找到buffer目录的inode,想找到buffer目录的inode,就必须先找到code的目录的inode。原创 2024-04-21 18:41:01 · 375 阅读 · 0 评论 -
LIUNX文件系统
了解文件系统,首先要了解磁盘是如何存储和读取数据的。原创 2024-04-18 17:37:53 · 581 阅读 · 0 评论 -
LINUX系统编程:缓冲区
缓冲区分成和先说结论,语言的缓冲区可以减少系统调用的次数进而提高向文件写入和读取的效率。向屏幕打印,无非就是向屏幕这个文件的缓冲区写入,然后在由操作系统刷新到显示器文件,这样显示器就可以显示内容了。直接调用系统调用,写到显示器文件的缓冲区,然后由操作系统刷新。原创 2024-04-14 20:54:55 · 305 阅读 · 0 评论 -
LINUX系统编程:stdin的实现
主要就是根据打开方式,打开文件,创建一个myFILE,返回个myFILE*即可。5.刷新的策略,不同文件的刷新策略不同,显示器文件为行刷新,普通文件为全刷新。C语言的输入接口,都会向FILE*stdin里面的缓冲区打印。fflush把当缓冲区的内容,清空,拷贝到系统的缓冲区。向c语言缓冲区写入,再根据刷新策略,刷新到系统缓冲区。首先我们要封装的就是FILE结构体。1.一个C语言的缓冲区buffer。fopen是对open的封装。这个结构体大概含有以下内容。3.当前缓冲区的大小。原创 2024-04-15 09:11:56 · 266 阅读 · 0 评论 -
LINUX重定向的原理
文件描述的分配规则:最小没有使用的下标会分给最新打开的文件正常printf打印是在stdin标准输出显示器打印,stdin标准输出显示器的fd是1。所以只要把显示器文件stdin给关闭,再打开一个文件,这个文件的 fd根据规则就会是1。但是在上层,printf打印只会向fd为1的文件的缓冲区打印,这样就完成了狸猫换太子。把log.txt的文件描述符打印到log.txt中。运行结果。原创 2024-03-06 21:08:21 · 417 阅读 · 0 评论 -
Lniux Shell外壳
简单说shell就是命令行解释器主要作用就是将我们的命令翻译给系统,在把系统处理结果反馈给使用者。一个操作系统从广义上来看如图 从狭义上看其实就是内核如图。原创 2023-10-25 19:59:13 · 87 阅读 · 5 评论 -
LINUX粘滞位
粘滞位其实是给other设置的一个权限位t,t具有x的意义,但是对设有粘滞位的目录进行了进一步的限定,设有粘滞位的目里的文件只有该文件拥有者和root有删除的权限,其他人一概不允许。原创 2023-11-05 10:25:04 · 147 阅读 · 3 评论 -
冯诺依曼体系结构
我们知道cpu的计算速度是非常非常快的,但是我们输入设备和输出设备的速度与cpu相比是非常缓慢的,如果输入输出设备与cpu直接进行交互,cpu估计会被闲死,cpu会一直在等输入和输出这个时候为了解决这个问题,内存就出现了,,这个时候计算机的效率就还不错了,最重要的是他让计算机的价格大幅度下降的同时,效率还有所保证,如果输入输出设备和cpu进行直接交互想要提升效率就必须增大cpu的高速缓存,高速缓存的价格是非常非常高的。1.计算机数据流动的方向是 输入设备 ->内存 ->cpu ->内存 ->输出设备。原创 2023-12-02 19:46:04 · 69 阅读 · 0 评论 -
LINUX普通用户如何sudo
4.按下i进入插入模式(右下角是insert说明是插入模式)9.重新进入底行输入q!7.shift + : 进入底行模式。1.首先我们要切换到root账号。5.将普通用户添加上去。6.ESC退出插入模式。原创 2023-11-05 08:04:05 · 227 阅读 · 1 评论 -
LINUX 权限
了解文件权限,如何修改文件权限原创 2023-11-05 10:05:07 · 94 阅读 · 1 评论 -
LINUX中进程调度算法
LINUX中有四种调度类(优先级从高到低),这里我们只介绍我们最常用的,完全公平类。原创 2023-12-10 10:58:40 · 93 阅读 · 0 评论 -
LINUX进程退出进程等待
1.进程退出1.1进程退出方式:1.2进程退出函数1.3退出码转化为错误描述2.进程等待2.1进程等待的必要性:2.2进程等待方法waitpid引言:创建一个进程,必然是要这个创建出来的进程去完成某种任务,该进程必须把任务的完成结果返回给其父进程,这就像打游戏 你接受了一个任务,任务完成后,还必须回去告诉发布任务的人,我完成这个任务啦,奖励才会到你的手。原创 2023-12-24 18:50:05 · 1181 阅读 · 0 评论 -
LINUX命令行参数
argc是这个命令行参数的个数argv是一个char*的指针数组,用来接收命令行参数,argv[0]存储的是可执行程序的路径,argv这个数组必须是以NULL结尾。原创 2023-12-19 11:27:11 · 378 阅读 · 0 评论 -
LIUNX进程程序替换
a.一个程序,只能执行自己的代码b.如果想要一个程序执行,别的程序的代码呢?我们就可以创建一个子进程,将这个子进程替换为我们想要执行的程序。原创 2023-12-29 16:39:03 · 394 阅读 · 0 评论 -
LINUX环境变量
环境变量是系统内置具有特殊用途的变量。环境变量本质其实就是我们在编程中的变量,因为linux操作系统就是用C语言和C++编写的。这个特殊用途可以指什么呢,了解linux的人都知道liunx的命令,其实大多数都是一个可执行的程序,但是为什么我们在执行命令的时候就不用加上路径,在执行自己的程序时就必须加上路径?这是因为在我们执行命令时,系统会在PATH环境变量中寻找我们可执行程序.我们用echo $PATH命令查看PATH环境变量的内容,在执行指令的时候会从这些路径寻找命令,每个路径用冒号隔开。原创 2023-12-18 17:00:41 · 837 阅读 · 0 评论 -
LINUX进程地址空间
有了上面的知识储备,我们也就能解释,为什么一个变量有两个值,地址是相同的问题。虽然这两变量的虚拟地址是相同的,但是别忘了,映射关系可以不同,修改一下映射关系,子进程pid地址就可以映射到物理地址的其他位置。下图可以非常清楚的表示。原创 2023-12-26 17:59:33 · 398 阅读 · 0 评论 -
LINUX文件fd(file descriptor)文件描述符
引言:在学习C语言的时候,我们见过很多的文件的接口,例如fopen,fwrite,fclose等等,但是仅仅凭借C语言的知识,我们并没有办法完全理解,只是知道怎么去用,希望看完这篇文章能加深你对文件的理解。原创 2024-01-21 20:05:11 · 988 阅读 · 0 评论