![](https://img-blog.csdnimg.cn/18d14e5e539b4ff3b6dd1c0277c527a3.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
Linux
文章平均质量分 88
个人对linux操作系统的知识总结
就要 宅在家
New git new get
展开
-
Linux——TCP协议与相关套接字编程
这里需要注意的是因为缓冲区的存在,一份数据可能会拆开来发送,这样接收方一次收到的数据可能就是不完整的,因此需要自定义通信协议(检测数据是否已经完整)确保目标数据完整后再使用,具体方式在套接字编程代码中会说明。当然,TCP的服务端处除了需要建立监听外,在连接一个客户端后,需要创建一个子进程负责和这个客户端通信,父进程则继续循环等待新的客户端来连接。但有一点需要强调,write和send的第一个参数在服务端是服务套接字,因为每一个客户端(对端)的服务套接字各不相同,使用服务套接字可以标定唯一的客户端。原创 2023-03-21 17:20:17 · 581 阅读 · 1 评论 -
Linux——UDP协议与相关套接字编程
套接字英文名为socket,直译是“插座”。插座是用于连接电源和电器,达到通电的效果。而套接字是让应用层与传输层通过IP和端口号port锁定其他网络中的进程来达到通信的目的。因此套接字由IP地址、端口号port以及通信协议方式(TCP/UDP)组成。我们知道,在网络通信中通过一个IP地址可以锁定一台主机,通过端口号可以锁定一台主机上某一个进程。因此IP地址+端口号可以锁定全网中唯一的进程,进而达到通信的目的。原创 2023-02-24 16:08:46 · 1544 阅读 · 8 评论 -
Linux——线程同步(条件变量、POSIX信号量)和线程池
thrmgr防止线程长期得不到调度的方式也很简单,当线程没有任务时,采用pthread_cond_timedwait函数阻塞等待,该函数第三个参数为设定的timespec时间类型结构体,当检测超时后自动停止阻塞并返回特定值,根据返回值就能判断线程是否是因为超时而停止阻塞,一旦判断超时,线程跳出等待任务的循环然后结束本线程。首先简单说一下什么是循环队列,本质就是长度固定的数组,从头开始插入资源,当插入资源位于最后一个位置的下一个时,再从头开始插入资源,也就是把线性的数组“头尾相连”,变成逻辑上的环形结构。原创 2023-02-15 00:00:00 · 938 阅读 · 7 评论 -
Linux——生产消费者模型(阻塞队列形式)
生产消费者模型是操作系统里非常经典模型,可应用于多线程并发协作,本质即通过一个容器(即缓冲区,本质是一种数据结构)来解决生产者与消费者的强耦合问题,也就是实现数据交互的低耦合。模型图示如下:在生产消费者模型中,生产者将产生的数据放入容器里,消费者从容器中获取数据来使用。而不是由生产者直接将数据“交给”消费者。相当于生产者把数据放入了一个“仓库”,消费者直接从“仓库”里拿,从而避免了生产者和消费者的直接接触。原创 2023-02-08 00:15:00 · 1503 阅读 · 11 评论 -
Linux——死锁概念介绍和解决方式
死锁指的是在多线程环境中,每个执行流(线程)都有未释放的资源,且互相请求对方未释放资源,从而导致陷入永久等待状态的情况。就好比和绑匪交赎金时,家属要求先放人再给钱,绑匪要求先交钱再给人,双方达不成一致意见,导致出现“僵死”的局面。程序层面而言,两个线程各加一个互斥锁mutex,在临界区中试图获取对方的互斥锁,陷入“互相请求对方的锁,但不释放自己锁”的尴尬局面,这就是死锁的一种场景。同一时间只能有一个执行流拥有资源执行流请求资源时,不能释放已有资源执行流已有资源不能被强制剥夺。原创 2023-02-03 00:00:00 · 1939 阅读 · 16 评论 -
Linux——什么是互斥与互斥锁
所谓互斥,其实就是在某一时刻只能有一个线程访问临界区,且完整的使用临界资源没有其他线程打扰,即原子性。简单来说就是当前线程使用完临界资源后其他线程才能来使用。互斥锁通俗来讲就是用来完成互斥行为的对象,锁住的范围一般就是临界区。需要互斥操作的多线程共享一个互斥锁,当一个线程获得互斥锁后,其他线程会阻塞等待,直到当前线程归还互斥锁后,其他线程争抢互斥锁,谁获得了谁能进入临界区执行代码。原创 2023-01-28 00:45:00 · 1214 阅读 · 5 评论 -
Linux——一文彻底了解进程id和线程id的关系(什么是pid、tgid、lwp、pthread_t)
首先,我们要清楚,在系统层面只有两个编号:pid、tgid。不妨拿出task_struct结构体(进程PCB)看一看:pid_t pid; pid_t tgid; 我们知道,在linux中进程和线程都使用task_struct结构体实现。在task_struct中:pid即线程id。也就是task_struct的编号,每个task_struct各不相同。tgid叫线程组id。也就是一个进程的id。同一个进程里每一个线程的task_struct中tgid值都一样。当使用ps axj或ps -aL查看进程原创 2023-01-21 00:00:00 · 5830 阅读 · 8 评论 -
Linux——线程概念及私有数据和优缺点
线程与进程共享虚拟地址空间、页表等内核数据结构、数据和代码。线程的数据结构理论上与进程的不同,但基于线程和进程的相似性,linux的线程数据结构依旧采用task_struct结构体,与进程的一致。但是其他的操作系统线程有专属的结构,与进程的不同。也就是说,linux没有真正意义上的线程结构,而是采用进程的task_struct结构体模拟的线程。即便线程与进程都采用task_struct结构体,但是内核数据结构依旧属于进程,线程只是与进程共享。原创 2023-01-17 02:30:00 · 974 阅读 · 5 评论 -
Linux——页表的分页机制
以32位机器为例,页框的个数为4GB / 4KB也就是2^20次方个,假设一个表项占有4Byte,总共有4MB的连续空间需要使用,也就是说,每次调度进程时,这4MB的空间都要被使用。每个页框4KB,共有4x1024个地址,即2^12次方,页内偏移即虚拟地址后12位,也是2^12次方,正好可以偏移出一个页框中全部地址。虚拟地址前20位是两级页表的索引,共能索引出2^20次方个页框,内存共4GB即2^20次方个页框,因此正好与之一一对应。linux将虚拟地址的32位分为前10位、中间10位、后置12位。原创 2023-01-15 00:30:00 · 1596 阅读 · 4 评论 -
Linux——信号知识归纳(下)
linux将进程的状态分为用户态(user mode)和内核态(kernel mode)。内核态时CPU执行代码不受任何限制,而用户态会做代码安全的相关检查,不能直接访问内核数据。一般而言,执行代码不会进入内核态,防止用户破坏内核数据和操作系统。但有时需要进入内核态,比如当执行系统调用接口时就是典型进程状态转换过程。以执行系统提供的open函数,其过程如下:1.进程执行到open的代码,CPU取得open函数地址。(用户态)2.跳转到open函数地址(在虚拟地址空间的内核区)。(用户态)原创 2023-01-13 00:00:00 · 965 阅读 · 4 评论 -
Linux——信号知识归纳(中)
硬件产生异常并使程序崩溃的方式有很多,比如除0错误、空指针、数组越界等。大致上,当硬件产生异常后,会“汇报”给操作系统,再由操作系统发送相关信号给进程,促使进程异常退出。以除0错误为例,当cpu检测到除0后,其中状态寄存器会标记异常,操作系统识别到该寄存器标记了异常后,发送信号给当前进程,进而进程崩溃退出。再比如空指针问题,当虚拟地址为空时,页表通过MMU(硬件)映射时会出错,MMU内部寄存器会标记异常,操作系统识别后发送信号给进程,进程崩溃退出。原创 2023-01-11 01:30:00 · 470 阅读 · 3 评论 -
Linux——信号知识归纳(上)
核心转储功能,应用于代码出错的调试,如果进程被信号异常终止且该信号有核心转储功能,那么就会生成一个数据文件到磁盘中,在gdb调试时可用于查看异常信息。信号是操作系统控制进程的一种方式,比如ctrl C、栈溢出程序崩溃、kill -9命令等底层都是操作系统发送信号给进程执行特定操作。同时,进程接收到信号后,不一定会立即处理,信号发送方也不一定会阻塞等待信号处理结果,即信号与进程是。其中,1 - 31号信号是普通信号,34 - 64号是实时信号。情况下,信号的处理方式就是不处理,接收后略过该信号执行过程。原创 2023-01-09 05:15:00 · 856 阅读 · 4 评论 -
Linux——详解共享内存shared memory
共享内存本质上就是内存中的一块区域,用于进程间通信使用。该内存空间由操作系统分配与管理。与文件系统类似的是,操作系统在管理共享内存时,不仅仅有内存数据块,同时还会创建相应结构体来记录该共享内存属性,以便于管理。因此,共享内存不只有一份,可以根据需求申请多个。进程之间进行通信的时候,会获取 到共享内存的地址,写端进程写入数据,读端进程通过直接访问内存完成数据读取。原创 2022-12-12 14:15:00 · 12857 阅读 · 4 评论 -
Linux——文件系统inode与软硬链接
值得注意的是,虽然一个文件只能有一个inode,但是一个inode可以对应多个文件名(这些文件本质是同一个文件,因为对应inode相同也就是使用的块相同)。同时inode中会记录映射的文件名数量(引用计数方式),当数量为0时才会真正删除文件信息。格式化时,并没有删除inode与block table内容,只是把映射取消,因为inode与block可以覆盖。当删除文件时,只需要把对应的bitmap置0,同时把inode映射取消即可。硬链接删除时也不会删除相关文件,但是硬链接与目标文件是同一个文件。原创 2022-12-06 09:45:00 · 847 阅读 · 4 评论 -
Linux——匿名管道、命名管道及进程池概念和实现原理
管道是linux中一种非常古老的进程间通信方式,本质上就是一个内存级的文件。一般用于父子进程间通信。概念上就是父进程与子进程共同使用一个管道文件来传输数据。虽然父子进程都有对管道的读和写功能,但在使用时只能读或者写,因此管道是单向通信,半双工模式。原创 2022-12-04 10:00:00 · 2264 阅读 · 9 评论 -
Linux——文件描述符(fd)与重定向、dup/dup2
操作系统根据调用的write的进程,通过task_struct结构体内部指针,找到files_struct,再通过files_struct内的fd_array指针数组,依照write传入的具体fd值(下标),找到对应的file结构体,就找到了相关文件。即标准输入、标准输出、标准错误。fd_array是一个数组,里面存放的是指针,每一个指针都指向一个file结构体。关闭一个文件时,fd_array中相关指针会指向空,当再其他文件打开时,按照从0开始寻找空指针的方式,找到该空指针,让其指向新的文件。原创 2022-11-24 09:45:00 · 2402 阅读 · 6 评论 -
Linux——gdb调试时多进程切换方法(attach/follow-fork-mode)
当在linux下运行的代码中有创建子进程的操作时,当进行gdb调试时会默认选择父进程进行调试,假如需要对子进程进行调试就需要使用特殊方法。共有两种方法可供选择:这个方式就是当进程运行时,获取进程PID然后在进入gdb调试时,通过attach指令调试PID对用的进程。本质就是指定PID然后调试,并不是真正的进程切换调试。示例代码:过程如下: mode的可供选择值有两个parent与child,对应父进程与子进程。这个只能选择fork的第一个子进程作为child进行调试。还是使用上述示例代码,过程如原创 2022-11-03 08:45:00 · 2580 阅读 · 2 评论 -
带你彻底搞懂缓冲区
所谓缓冲区,就是当我们在编程向文件中输入数据时,数据无法直接写入文件,而是先写入一个名为缓冲区的区域,经过对缓冲区的刷新后才能写入文件中。可以通过此例作以证明:下例中,我们打开一个文件,使用fwrite向其中输入数据,第一次采用直接使用close关闭文件,第二次采用刷新缓冲区fflush后close关闭文件。//代码一int main(){//系统调用接口,fileno:即文件描述符fdreturn 0;}//代码二int main(){//刷新缓冲区return 0。原创 2022-10-26 08:45:00 · 3683 阅读 · 5 评论 -
Linux——详细模拟实现shell(进程控制综合运用)
因为虽然子进程确实进行了路径切换,但是在切换后进程就终止了,当再创建子进程时还是继承自父进程所在的原路径,相当于路径没变。因此我们想要改变路径就要让父进程改变路径,但是父进程又不能够用进程替换,又因为进程替换成功不会返回原有进程,我们需要一个子进程来执行每次具体的系统命令,父进程来完成shell的“轮回”——当子进程(系统命令)执行完毕后父进程重开一个新shell接收新指令。还有我们输入的ls指令是无色的,但是真正的shell是有颜色的,这个只需要我们在命令行参数中再加入"--color=auto"即可。原创 2022-10-10 07:45:00 · 1742 阅读 · 6 评论 -
Linux——详解进程控制之终止
在CPU运行完我们编写的代码后,执行到return 0时,就会结束当前进程。因此,main函数中的return 0的含义就是代码正确执行完毕,进程终止。,将0值(return值)作为参数status给exit(),在exit()内部清空缓冲区后,调用_exit终止进程,记录退出码status。由此,我们引来问题,为什么return在main中会终止进程而其他函数中不会呢,为什么return 0能结束进程呢。,作用是标志一个函数结束,即函数栈的返回。此外,_Exit与_exit是等价的,但头文件不同。原创 2022-09-30 15:24:44 · 2298 阅读 · 4 评论 -
Linux——详解进程控制之替换
与之前execl、execv相同,环境变量传链式结构或指针数组。filename传入文件绝对/相对路径+文件名。*envp[]传入带有环境变量的指针数组。当然最后应以NULL结尾。当创建失败时,函数会返回-1并在errno中记录该错误原因。errno是一个系统参数,由操作系统直接维护,会记录最新的错误。除此之外,execl、execv、execlp、execvp、execle都是在第三手册中,只有execve在第二手册中。原创 2022-09-29 09:44:12 · 852 阅读 · 2 评论 -
Linux——详解进程控制之等待
进程等待是进程控制中非常重要的一环,这关系着多进程之间的联动。进程等待是父进程等待子进程退出的过程。在等待中父进程可以选择阻塞或非阻塞状态。阻塞状态:父进程等待过程中不进行任何操作,进入挂起状态,本质是将父进程PCB放入等待队列(wait_queue)。非阻塞状态:父进程在等待过程中继续执行自己代码,即父进程一直处于运行状态。进程等待常用的两个函数接口是wait与waitpid。本质上,在waitpid内部会对options进行判断。当值为0时,将进程挂起,从而父进程进入阻塞状态,然后死循环判断子进程是原创 2022-09-26 15:11:39 · 1599 阅读 · 10 评论 -
Linux——详解进程控制之创建
创建进程是编程的常见操作。本节我们将对创建进程进行学习。原创 2022-09-23 16:20:13 · 1193 阅读 · 6 评论 -
Linux——进程地址空间
在我们刚学习计算机时,就知道栈区、堆区、常量区...的概念。那时候总以为计算机内存(物理内存)就是按这样排序的。但是,这不是物理内存,这是进程地址空间!(一).进程地址空间内部结构这里小编选择用一张图来表示其内部结构:(二).进程地址空间的产生当程序运行时,操作系统不仅将文件加载进进程、创建PCB结构体,还会创建一个mm_struct结构体。mm_struct结构体就是我们所谓的进程地址空间。我们在写代码时的那些所谓地址,其实都是mm_struct结构体规定的地址。这些地址并不真实存在。原创 2022-09-15 17:14:07 · 1184 阅读 · 8 评论 -
Linux指令——crontab
crontab指令安装和具体使用原创 2022-08-30 17:47:27 · 3360 阅读 · 8 评论 -
linux—常用gdb调试命令汇总
如果是函数递归调用,当还没开始递归时,finish会执行完整个函数,自动走完全部递归过程(前提无断点)。因为在linux系统下,默认生成的可执行程序是release版,但是调试需要debug版本。*gdp会自动记录最近的命令,如果没有输入其他命令,可以按enter键继续执行最近命令。需要注意的是,不能直接写变量名,变量编号使用infodisplay即可知道。如果我们需要在调试中一直显示某个变量的值,那么就需要display命令了。需要注意的是,这种方法只能显示一次变量值,当继续调试时变量不再显示。...原创 2022-07-30 17:18:09 · 19477 阅读 · 13 评论 -
vim基础操作汇总(模式转换、普通模式下操作、分屏)
vim是linux下一款文件编辑器,本篇文章小编将重点普通模式下的操作以及模式之间的转换和分屏切换。原创 2022-07-23 18:43:24 · 1623 阅读 · 9 评论 -
详解linux权限操作(概念、chown、chmod、chgrp、umask、粘滞位)
本文介绍了权限的概念和chmod,chown,chgrp,umask,粘滞位的概念和使用方式原创 2022-07-21 15:47:53 · 791 阅读 · 7 评论 -
Linux基础命令指南
本次共总结32个常用基础linux命令,包含使用和注意事项。原创 2022-07-14 12:59:35 · 372 阅读 · 10 评论