《深入Linux内核架构与底层原理》读书笔记三——进程

进程是满足用户需求的一系列正在执行的任务。进程这个概念不是一开始就存在的,是随着人们需要处理的业务逻辑越来越复杂,需要并发执行多种任务,分时分配CPU资源,才逐渐发展出来的一个概念。进程在Linux中被组织为父子关系,子进程退出时,父进程需要调用wait或waitpid函数等待回收子进程的资源,否则子进程就一直以“僵尸”状态存在。

1、ptrace系统调用
ptrace系统调用,可以强制让一个进程成为另外一个进程的父进程,可以深入的对子进程进行流程控制。在Linux下有几个常用工具是基于ptrace系统调用的,大多用于做普通的程序分析,尤其是内存数据的审查和修改。
ptrace是以线程为单位的,如果一个进程有多个线程,父进程就需要分别ptrace所有的线程。这的动作存在一定的风险性,如果一个多线程的程序在设计的时候没有考虑支持ptrace,那么需要谨慎使用,否则容易影响到进程整体的执行。
一些基于ptrace实现的常用工具:
  • strace: 打印进程调用的所有系统调用;
  • ltrace: 打印进程涉及的库函数调用的分析;
  • ftrace: 是一个跟踪二进制内容的函数调用的工具;
  • gdb attach: 可以直接使用gdb进行进程attach。

2、资源锁和资源限制
内核中的资源锁有:
  • 自旋锁
  • 信号量
  • 互斥锁
  • 读写锁
  • 顺序锁
  • RCU锁
  • futex锁
每一种锁都是用于解决某一种类型的问题。

futex是唯一一种由用户空间进程使用的锁,其实用户态很多高级语言的锁就是封装的futex,因为其高效,行为又符合要求。futex的核心思想就是直接将内核态的这个锁变量mmap映射到用户空间中,这样各个用户进程就可以在自己的空间中直接查询这个值了,不用再进入到内核态。但是,如果要写入时,仍然是需要通过Linux提供的API陷入内核来加锁的。
最有效的资源访问方式是不加锁,大部分的问题都可以使用无锁设计解决。但这也会带来内存上更大的损耗和代码管理上的难题。

互斥概念与同步概念
  • 互斥是指同一时间只有一个进程可以访问资源,没有时序概念;
  • 同步则包含了多个访问该资源进程的访问的先后顺序。
  • 信号量是属于同步概念的,因为未得到资源的进程会睡眠等待。其他的内核锁是互斥概念的,如自旋、顺序,得不到就阻塞。
资源限制常用cgroup,随着Docker的成熟,得到了广泛的使用。cgroup可以限制cpu、内存、文件、行为等,甚至是系统调用。
在这之前,也可以独立使用getrlimit和setrlimit这两个系统调用进行资源限制。
如果是在做一个可发布的应用程序,rlimit仍是一个不错的资源限制的选择。

3、进程对系统内存的使用
  • 大部分进程通过glibc申请使用内存,但glibc也是一个应用程序库,它最终是调用操作系统的内存管理接口来使用内存。
  • 少数情况下,glibc在处理大量并发小内存的时候会出现内存泄漏。
  • 进程申请了1GB内存,但并不一定需要这么多的物理内存。内核虽然也批准了,但只有在进程需要实际使用内存而引发缺页异常时,才会真正给它安排实际的内存。当所有进程都要求兑现申请的全部内存时,内核不一定能做到全部兑现。因此会崩溃。这个情况下会根据当前每个进程的OOM分数选择当前分数最高的进程直接杀死。这些操作的记录可以在/var/log/kern.log中查看到。

进程的内存种类:
  • 堆,用来存放数据;
  • 栈,用于执行进程;
  • VIRT,进程的虚拟地址空间大小;
  • RSS,进程实际正在使用的物理地址的大小;

查看一个进程资源的最好方法是使用/proc/pid/stat*中的三个文件:
  • statm: 是关于进程的内存使用信息的;
  • status: 是一个可读性好的、用户通常会比较关心的内容。
  • stat: 是非常全面的信息,如进程号、缺页次数、启动时间、信号、CPU、进程组等。
此外,smaps中有非常详细的进程内部内存的映射情况。maps提供了内存映射的一个概览。

操作系统层面与内存分配有关的两个系统调用:
  • brk
  • mmap
这两种方式都是分配虚拟内存,没有分配物理内存。

4、多进程与进程通信
进程是被制造出来的一个概念,只是一个存在于理论上的概念模型,它实际上是一种结构体task_struct,使用pid进行定位。是内核如何处理进程概念的引入带来的一系列代价。

目前用户进程通信,最好的选择仍旧是System v IPC(POSIX IPC)的三种方法:
  • 信号量,一般用于资源限制
  • 共享内存,因为需要手动地组织内存的安排,非常复杂;
  • 消息队列,是比较常见的通信方案
有大量数据通信需求的很多服务也喜欢采用UNIX Domain Socket,一个原因是这个方式的使用与普通socker方式没什么区别。

内核与用户空间的进程通信:Netlink
Netlink是用户程序与内核通信的socket方法。通过Netlink可以获得修改内核的配置。

Netlink功能模块:
  • NETLINK_ROUTE,用来与邻居表、路由表、数据包分类器、网卡信息等子系统通信,获取信息或者进行设置。
  • NETLINK_W1
  • NETLINK_USERSOCK
  • NETLINK_FIREWALL
  • NETLINK_INET_DIAG,用于同网络诊断模块通信
  • NETLINK_SELINUX
  • NETLINK_ISCSI
  • NETLINK_AUDIT
  • NETLINK_CONNECTOR
  • NETLINK_GENERIC
  • NETLINK_CRYPTO

inet_diag模块:
inet_diag和tcp_diag是两个模块,但都是使用inet_diag的接口。inet_diag又是使用Netlink的接口。
经常使用的ss命令,就是使用的inet_diag模块实现的。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
深入Linux内核架构底层原理》是一本介绍Linux内核的经典书籍,主要围绕Linux内核的设计、架构和实现原理展开讲解。 该书首先介绍了Linux内核架构,包括进程管理、内存管理、文件系统、网络、设备驱动等方面。通过对Linux内核各个模块的功能和相互关系的剖析,读者可以对Linux内核的整体结构有一个全面的了解。 接着,书中详细讲解了Linux内核底层原理。包括线程、进程进程调度、内存管理、虚拟文件系统、网络协议栈、设备驱动等方面的内容。通过对这些底层原理深入讲解,读者可以了解到Linux内核是如何实现这些功能的,并且能够更好地理解和分析Linux内核的代码。 此外,该书还着重介绍了Linux内核的设计哲学和设计思路。作者通过对多个实际案例的分析,向读者展示了Linux内核是如何通过简洁、灵活的设计和实现来提高性能和可扩展性的。这对于研究Linux内核的读者来说非常有价值,可以帮助他们更好地理解Linux内核的设计思想,从而更好地应用和开发Linux系统。 总之,《深入Linux内核架构底层原理》是一本关于Linux内核深入研究的书籍,通过系统地介绍Linux内核架构底层原理,帮助读者全面了解和理解Linux内核,并能够更好地应用和开发Linux系统。它不仅适合Linux内核的研究者和开发者阅读,也适合对Linux系统感兴趣的读者阅读。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值