linux 综合
文章平均质量分 91
linux 进程管理和调度,信号,内核模块等
王燕龙笔记
linux学习总结
展开
-
实例观察 linux 内存懒加载和写时拷贝
linux 中写应用程序的时候,使用 malloc() 申请的内存,比如使用 malloc() 申请了 1MB 的内存,系统是立即分配了内存吗?linux 中用户态的内存是懒加载的,不是申请之后就立即分配,而是在第一次访问的时候才会分配。(1)避免内存资源浪费,如果应用申请了内存但是一直没有使用,如果内存是立即分配的话就会导致很多内存资源浪费。懒加载类似于单例设计模式中的懒汉式。(2)减少初始化开销,提升应用启动速度。在进程启动的时候,不需要立即给所有的虚拟内存分配物理内存,这样可以减少初始化开销。原创 2024-03-12 10:43:44 · 1387 阅读 · 0 评论 -
[linux] linux 下怎么定位内存泄漏 + free,buddyinfo
正常情况下,软件使用的内存是随着时间在一定范围内波动的。内存泄漏说的是随着时间的推移,进程使用的内存越来越多。一般情况下,内存泄漏是程序不断地申请内存,但是没有释放导致的。原创 2024-02-27 14:55:33 · 1558 阅读 · 0 评论 -
linux 中 fd 的几点理解
fd 全称是 file descriptor,文件描述符,又称句柄。当我们在打开一个文件,创建一个 socket, 创建一个 epoll 时,返回值往往都用一个变量 int fd 来表示。原创 2024-01-13 10:35:03 · 1636 阅读 · 1 评论 -
linux 中 fd 申请和释放管理(两级 bitmap)
通过上边的文章,我们可以知道,在 linux 中,fd 有以下几点需要了解:(1)fd 表示进程打开的文件,是进程级别的资源,不是系统级别的资源(2)struct task_struct 在内核中用于描述一个进程,其中打开的文件使用 fd table 来描述(3)在用户态看 linux,一些皆文件(4)一个进程可以打开的文件个数是有限制的,使用 ulimit -a 可以查看可以想象,如果让我们自己来实现的话,我们会选择一个 bitmap 来维护 fd 的被使用情况。原创 2024-05-20 22:28:21 · 857 阅读 · 0 评论 -
linux软链接和硬链接的区别
如下图所示,一开始有两个文件soft和hard。使用 ln -s soft soft1创建软链接,soft1是soft的软链接;使用ln hard hard1创建硬链接,hard1是hard的硬链接。可以看到软链接的文件类型和其它3个文件的文件类型是不一样的,软链接的文件类型是l开头的。原创 2024-07-07 10:08:18 · 373 阅读 · 0 评论 -
linux中可执行文件为什么不能拷贝覆盖
如下的代码,使用 gcc hello.c -o hello, gcc hello.c -o hello1分别编译出两个可执行文件hello和hello1,然后执行hello,再执行cp hello1 hello,这样会报错。如果可执行文件没有被执行,那么是cp命令是可以执行成功的。可执行文件被执行的时候,通过execve系统调用来进行。对于一个普通的文件,假如有两个文件,分别是file和file1,我们使用 cp file1 file的方式使用file1的内容来覆盖file的内容,这样是可以的。原创 2024-07-07 10:55:57 · 236 阅读 · 0 评论 -
cgroup memory使用超过限制会怎样?
cgroup可以对一个进程或者一组进程使用的资源进行限制,可以限制的资源包括cpu、memory、io等。其中memory可以对内存资源进行限制,比如我们限制进程所能使用的内存最大是1G,那么当进程已经使用了1G的内存的时候,这个时候进程再申请内存会怎么样呢?内存使用超过限制的时候有如下两种结果:(1)默认情况下,内存使用超过限制,会oom(out of memory),oom的时候系统会使用SIGKILL信号将进程杀死。(2)cgroup中也可以进行配置,oom的时候不杀死进程,此时进程进入D状态。原创 2024-07-06 10:56:31 · 946 阅读 · 0 评论 -
system 和 exec 的区别
在 linux 中,使用 system 和 exec 都可以执行一个程序或者执行一个命令。两者的区别如下:system 中创建了一个子进程,在子进程中执行用户的命令,子进程执行完毕之后,system 会返回。exec 不会创建子进程,而是直接用 exec 要执行的进程来代替当前的进程,并且如果在执行过程中没有出现错误,那么 exec 是不会返回的,调用 exec 的进程永远也回不来了。原创 2024-06-09 19:44:03 · 919 阅读 · 0 评论 -
性能优化随笔(一)
在软件开发过程中,一般要先实现功能方面的需求,功能方面的需求开发完毕之后,往往会考虑性能方面的优化。在业务发展的初期,性能往往能满足使用的需求,这时性能优化不是必不可少的。随着业务的发展,软件复杂度的提高,性能有时会成为瓶颈,这时性能优化是必须要做的工作。原创 2024-06-02 20:43:00 · 1635 阅读 · 2 评论 -
linux 内核哪种锁可以递归调用 ?
当数据被多线程并发访问(读/写)时,需要对数据加锁。linux 内核中常用的锁有两类:自旋锁和互斥体。在使用锁的时候,最常见的 bug 是死锁问题,死锁问题很多时候比较难定位,并且影响较大。本文先会介绍两种引起死锁的原因,对比自旋锁和互斥体的区别,最后记录一下可以递归调用的锁。本文通过内核模块来展示锁的使用。锁保护的是数据,不是代码。数据在代码中要么是一个变量,要么是一个数组,一个链表,红黑树等。原创 2024-06-01 18:59:41 · 896 阅读 · 2 评论 -
fork、exec 踩坑记录
在 linux 中,使用 fork 创建的子进程,子进程共享着父进程的资源,这些资源包括内存,信号,打开的文件等。就如同刚出生的小孩,和父母共享着家里的房子,存款等。(1)内存不需要我们特别关心,因为系统的写时拷贝保证了,在写的时候,父子进程的内存是分离的。(2)信号需要我们注意,在 fork 之后,子进程和父进程的共享着信号处理函数,如果不想共享,那么可以使用 signal 来修改信号的行为。原创 2024-05-22 21:54:37 · 554 阅读 · 0 评论 -
linux tasklet
软中断、tasklet 以及工作队列,均是 linux 中将任务推后执行的机制。其中工作队列与用户态使用的线程池类似。什么是任务推后执行呢?可以借助于开发应用时经常使用的线程池来理解。任务推后执行,就是任务本该执行的时候没有立即执行,而是将任务放到任务容器(标志位或者任务队列)中,相当于生产者;任务容器还有消费者,消费者从容器中取出任务来执行。这就是推后执行,其中有 3 个组成元素,生产者,任务容器和消费者。原创 2024-04-02 18:18:55 · 1107 阅读 · 0 评论 -
linux 软中断
在 linux 中,任务执行的载体有很多,包括线程,中断,软中断,tasklet,定时器等。。软中断和 tasklet 的执行可能在中断中,也可能在线程中,定时器的执行可能在中断、软中断或者线程中。在讨论中断和软中断的时候,经常以网卡收包为例子来理解。如下是网卡收包的主要环节,分别说明每个环节:① 网卡从链路上收包,网卡的作用是成帧,网卡在链路上收到的是字节流,根据前导码,帧开始界定符,帧间隙来界定一个帧,这就是成帧。② 网卡界定一帧报文之后,将这一帧报文通过 dma 保存到内存中。原创 2024-03-31 22:01:53 · 1370 阅读 · 0 评论 -
linux 内核模块入门
内核模块可以动态地被安装到内核,从而扩展内核的功能,使用内核模块时不需要重新编译内核。内核模块常用的场景是驱动,随着芯片种类的增加,硬件种类的增加,这些芯片或者硬件(比如网卡) 的驱动可以以模块的方式进行开发,这样可以在需要的时候加载对应的模块,不使用的时候卸载模块,不至于因为芯片或硬件的种类的快速增加而导致内核镜像的膨胀。使用 lsmod 可以看到当前系统中安装的内核模块。字符设备,块设备,网络设备,文件系统等都可以通过内核模块的方式来安装。原创 2024-03-31 13:09:31 · 1122 阅读 · 0 评论 -
linux 中进程的 D 状态和 Z 状态
僵尸态是 linux 进程的一种状态,用 Z (zombie) 表示。处于 Z 状态的进程已经不在工作,进程的资源(内存,打开的文件) 都已经释放,只保留 struct task_struct 一个空壳子,用僵尸来表示这个状态非常形象。僵尸进程不能被信号杀死(因为僵尸进程已经死了,当然也不能响应信号),只能被父进程回收。进程处于僵尸态时保存的信息非常少,其中包括进程号,退出码,退出码是比较重要的,父进程回收僵尸进程的时候可以根据退出码确定子进程的退出原因。原创 2024-01-13 11:05:54 · 2525 阅读 · 0 评论 -
linux 中平均负载统计时包括了 D 状态的线程
linux 中平均负载的统计中包括了 TASK_RUNNING 的线程以及 TASK_UNINTERRUPTIBLE 的线程。原创 2024-01-19 20:52:16 · 833 阅读 · 0 评论 -
SCHED_FIFO 和 SCHED_RR 同时存在时,如何调度
(1)从上边的实验现象可以看出来,实验现象符合 SCHED_FIFO 先入先出,SCHED_RR 时间轮询的调度原理。(2)在实时调度策略中,高优先级具有绝对的优先调度的的特权,即使 SCHED_RR 这种时间片轮询的调度算法,也是说的多个 SCHED_RR 的优先级相等的前提下才会轮询,如果优先级不相等,那么只会调度优先级最高的那个线程。原创 2024-01-19 21:03:55 · 1464 阅读 · 0 评论 -
linux 调度策略的几点理解
在内核中, 调度策略的优先级大小关系如下:优先级在用户,内核, top 中的对应关系:调度策略用户top内核nice 值 [-20, 19][0, 39][100, 139][-2, -100], 其中 -100 在 top 命令中显示为 rt-1 - x[0, 98]优先级不需要设置显示为 rt-1在 top 命令以及内核中,数值越小,优先级越高。原创 2024-01-25 21:06:34 · 1208 阅读 · 0 评论 -
offsetof,container_of
那么可以使用 offset 宏计算成员 member 相对于 struct Cotainer 的偏移量,也可以通过 member 的地址获取到结构体 struct Container 的地址。结构体可以看作这个成员的容器,所以 container of,一个成员的容器。offset 和 container_of 两个宏在内核中的定义如下,可以看到 container_of 中还使用了 offsetof。offsetof: 计算结构体的成员相对于结构体的地址的偏移量。原创 2024-01-28 20:34:37 · 439 阅读 · 1 评论 -
jetson agx orin 实时内核 调度延时测试
jetson agx orin 是 nvidia 推出的计算平台,在自动驾驶领域得到广泛应用。确定性执行是自动驾驶系统的基本要求,而任务调度的确定性是影响确定性执行的重要因素。本文测试了 jetson agx orin 的调度延时,对比测试了两种情况:打实时内核补丁和不打实时内核补丁。从测试结果来看,对于 rt 调度策略来说,打了实时内核补丁之后,最大调度延时在 70μs 以内;而不打实时内核补丁的话,最大调度延时在 1000μs 以上,差别还是比较明显的。原创 2024-02-05 13:47:27 · 1368 阅读 · 1 评论 -
实例观察优先级翻转和优先级继承现象
当两个优先级不同的线程同时存在于调度队列的时候,我们预期的调度顺序是:优先级高的线程先运行,优先级低的线程后运行。优先级翻转的意思是,当两个优先级不同的线程同时存在时,高优先级的线程得不到调度,而是低优先级的线程获得了执行的机会,与预期的执行顺序是反着的,所以称为优先级翻转。当讨论优先级翻转和优先级继承的时候,更多的是在讨论 linux 内核实时补丁的时候。我们知道,在没有打实时内核补丁的内核中,使用自旋锁时是关闭抢占的。原创 2024-02-05 16:44:25 · 1018 阅读 · 1 评论 -
使用cgroup踩过的坑
cgroup 全称 control group,控制组。通过 cgroup 可以限制应用使用的资源,资源包括 cpu、内存、磁盘 io、网络等。工作中经常使用的 docker 容器就使用了 cgroup 进行资源限制和隔离,cgroup 是 docker 的基础。原创 2024-02-18 22:08:43 · 1803 阅读 · 0 评论 -
ftrace,kprobe,tracepoint 入门
调试工具在开发过程中是必不可少的,特别是在定位 bug, 分析性能瓶颈的时候,调试工具可以给我们很大的帮助。在使用 c/c++ 做应用开发时,gdb 是我们经常使用的调试工具,在使用 gdb 时, 我们可以设置断点,查看调用栈,单步执行,修改或查看变量等。调试工具可以帮助我们直观地观察到软件的运行过程,进而使我们快速熟悉一个新的软件。比如在工作中,想要了解已有软件的架构,只靠看代码是很难了解透彻的,通过日志和调试工具可以提高学习效率。原创 2024-02-21 11:26:04 · 1254 阅读 · 0 评论 -
[linux][异常检测] hung task, soft lockup, hard lockup, workqueue stall
hung task,soft lockup,hard lockup,workqueue stall 是 linux 内核中的异常检测机制,这 4 个检测均是通过时间维度上的检测来判断异常。在时间维度上的检测机制,有两个核心的点:(1)一个表示被检测对象最新状态的变量这个变量可以用时间戳表示,也可以是一个计数器。(2)一个定时器这个定时器内部做检测工作,检测的依据就是状态变量。如果状态变量是时间戳,那么直接将时间戳和当前时间比较看看是不是超时;原创 2024-02-21 21:47:59 · 1105 阅读 · 0 评论 -
[linux] linux 常见信号以及使用信号时注意事项
信号相对于用户态的线程,类似于中断相对于内核态的线程。在内核态做开发时,如果数据会被线程和中断同时访问,在线程中我们需要使用关中断自旋锁,在中断处理函数中需要使用自旋锁。这样在线程访问数据的时候,中断是关闭的,所以这个时候中断也上不来,不会打断线程的执行。原创 2024-03-02 20:45:23 · 1132 阅读 · 0 评论 -
[linux][调度] linux 下如何观察线程调度延时 ?
linux 内核提供了一个内核观测工具 tracepoint。关于 tracepoint,可以参考如下博客。[linux][观测] ftrace,kprobe,tracepoint 入门简单来说,tracepoint 就是内核在一些关键位置进行了埋点,当这些关键事件发生的时候,会打印一些信息。比如在内存管理方面,有 kmalloc 相关的埋点,在申请内存或者释放内存的时候,可以打印一些信息;在 tcp 协议栈中也有一些埋点,当 tcp 发生重传的时候,或者收到 rst 报文的时候,也可以打印对应的信息;原创 2024-03-10 17:08:46 · 1385 阅读 · 0 评论 -
[linux][调度] 内核抢占入门 —— 线程调度次数与 CONFIG_PREEMPTION
当打开内核抢占时,也就是定义了 CONFIG_PREEMPTION 这个宏。那么打开这个宏的时候,具体定义了那些内容呢?本人使用的源码版本是 5.10.186。原创 2024-03-22 17:16:30 · 1168 阅读 · 0 评论 -
linux 内核抢占入门 —— 高优先级线程被唤醒时会立即抢占当前线程吗 ?
在支持抢占的内核中,如果高优先级的线程被唤醒的时候,这个时候 cpu 被其它线程占用着,并且正在运行的这个线程的优先级比刚被唤醒的这个线程优先级低。在内核抢占中,有两种类型的点,一个是检查点,一个是抢占点。在检查点的地方会做检查,如果需要抢占,那么会设置一个需要抢占的标志,但是在检查点的时候不做真正的抢占;真正的抢占是在抢占点,抢占点会判断检查点中设置的标志,如果需要抢占并且允许抢占的话,那么就会进行抢占调度。原创 2024-03-23 11:59:15 · 1648 阅读 · 0 评论