Linux 进程管理

本文详细介绍了Linux系统中的进程管理,包括进程的概念、组成部分、子父进程关系、特殊进程如idle、init和kthreadd,以及进程的优先级、/proc文件系统、信号、ps和top命令的使用、strace追踪系统调用、lsof查看进程打开文件等。通过这些内容,读者可以全面了解如何在Linux中监控和管理进程。
摘要由CSDN通过智能技术生成

1.1 什么是进程?

进程是 UNIX/Linux 用来表示正在运行的程序的一种抽象概念,所有系统上面运行的的数据都会以进程的形态存在。

1.2 进程的组成部分

一个进程由一个地址空间和内核内部的一组数据公同组成,地址空间是由内核标记出来供进程使用的一组内存页面(页面是管理内存的单位,页面大小通常是 1KB 或 8KB)。它包含进程正在执行的代码、库、进程变量、进程栈以及进程正在运行时内核所需要的各种其他信息。

内核的内部数据结构记录了有关每个进程的各种信息,其中非常重要的一些信息有:

  • 进程的属主;
  • 进程的信号掩码(一个记录,确定要封锁哪些信号);
  • 进程已打开的文件和网络端口的信息;
  • 进程执行的优先级;
  • 进程的当前状态(睡眠状态、停止状态、可运行状态等等);
  • 进程的地址空间映射。

1.3 子进程与父进程

每个进程都有一个唯一的 PID(Process ID),进程必须克隆自身去创建一个新进程。克隆出的进程能够把它正在运行的那个程序替换成另一个不同的程序。

当一个进程被克隆时,原来的进程就叫做父进程 PPID(Parent Process ID),而克隆出的副本则叫做子进程。进程的 PPID 属性就是克隆它的父进程的 PID

我们以一个实例加深对子进程与父进程的理解:在目前的 bash 环境下,再出发一次 bash ,并以 ps -l 命令观察进程 PIDPPID 的输出信息。

[root@web ~]# ps -l     //第一个 bash 的 PID 是 1363
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  1363  1322  0  80   0 - 28864 do_wai pts/1    00:00:00 bash
0 R     0  1484  1363  0  80   0 - 38314 -      pts/1    00:00:00 ps
[root@web ~]# bash    //执行 bash 进入到子程序的环境中      
[root@web ~]# ps -l  //第二个 bash 的 PID 是 1487 , 它的 PPID 就是第一个 bash 的 PID 1363 
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  1363  1322  0  80   0 - 28864 do_wai pts/1    00:00:00 bash
4 S     0  1487  1363  0  80   0 - 28864 do_wai pts/1    00:00:00 bash
0 R     0  1500  1487  0  80   0 - 38314 -      pts/1    00:00:00 ps

1.4 特殊进程

Linux 有三个特殊进程,idle 进程(PID=0),init 进程(PID=1),kthreadd(PID=2)。

idle 进程

idle 进程由系统自动创建的第一个进程, 运行在内核态,也是唯一一个没有通过 fork 或者 kernel_thread 产生的进程。完成加载系统后,演变为进程调度、交换。

init 进程

Linux 的所有进程都是有 init 进程创建并运行的。首先 Linux 内核启动,然后在用户空间中启动 init 进程,再启动其他系统进程。在系统启动完成完成后,init 将变为守护进程监视系统其他进程。

在我的 CentOS 7 系统里面,可以 ls 看到 init 进程是被软连接到 systemd 的。

[root@web ~]# ls -al /usr/sbin/init
lrwxrwxrwx 1 root root 22 Apr 26 11:07 /usr/sbin/init -> ../lib/systemd/system

系统启动之后,init 进程会启动很多 daemon 进程,为启动运行提供服务,比如 httpd、ssh 等等,然后就是 agetty,让用户登录,登录后运行 shell(bash),用户启动的进程都是通过shell 运行的。

执行 ps -ef 命令会发现 PID 1 的进程就是我们的 init 进程 systemd ,PID 2 的进程是内核现场 kthreadd ,这两个在内核启动的时候都见过,其中用户态的不带中括号,内核态的带中括号。

[root@web ~]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0  2019 ?        00:12:54 /usr/lib/systemd/systemd --system --deserialize 24
root         2     0  0  2019 ?        00:00:01 [kthreadd]
root         3     2  0  2019 ?        00:03:10 [ksoftirqd/0]
root         5     2  0  2019 ?        00:00:00 [kworker/0:0H]
root         7     2  0  2019 ?        00:00:00 [migration/0]
...
root     23086 23085  0 10:23 pts/3    00:00:00 su - root
root     23087 23086  0 10:23 pts/3    00:00:00 -bash
root     24529     2  0 16:28 ?        00:00:00 [kworker/0:2]
root     25448     2  0 16:33 ?        00:00:00 [kworker/0:0]
root     25861     2  0 16:36 ?        00:00:00 [kworker/u2:0]
root     25863     1  0 Mar20 ?        01:58:45 /usr/local/qcloud/YunJing/YDEyes/YDService
root     25916     1  0 Mar20 ?        00:06:03 /usr/local/qcloud/YunJing/YDLive/YDLive
root     26359     2  0 16:38 ?        00:00:00 [kworker/0:1]
root     26957     2  0 16:42 ?        00:00:00 [kworker/u2:1]
root     27254 23087  0 16:43 pts/3    00:00:00 ps -ef
root     27732     1  0 Apr28 ?        00:00:00 ./fork.o
root     29944     1  0 Apr06 ?        00:18:37 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --ex
root     29949 29944  0 Apr06 ?        00:12:40 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --star
root     30648     1  0  2019 ?        00:00:00 /usr/lib/systemd/systemd-udevd
root     30936     1  0  2019 ?        00:01:06 /usr/sbin/crond -n
chrony   32061     1  0  2019 ?        00:00:07 /usr/sbin/chronyd

sshd 的父进程是 1,pts 的父进程是 sshd,bash 的父进程是 pts,ps -ef 这个命令的父进程是 bash,这样这个子父进程的关系就比较清晰了。

[root@web ~]# ps -ef|grep sshd
root      1299     1  0 12:06 ?        00:00:04 /usr/sbin/sshd -D
root      6008  1299  0 16:49 ?        00:00:00 sshd: root@pts/0
root      6415  1299  2 17:07 ?        00:00:00 sshd: root [priv]
sshd      6416  6415  0 17:07 ?        00:00:00 sshd: root [net]
root      6420  6012  0 17:07 pts/0    00:00:00 grep --color=auto sshd
[root@web ~]# ps -ef|grep bash
root      6012  6008  0 16:49 pts/0    00:00:00 -bash
root      6457  6012  0 17:10 pts/0    00:00:00 grep --color=auto bash
[root@web ~]# 

kthreadd 进程

kthreadd 进程由 idle 通过 kernel_thread 创建,并始终运行在内核空间,负责所有内核线程的调度和管理,所有的内核线程都是直接或者间接的以 kthreadd 为父进程。

1.5 进程的优先级

Linux 是多人多任务的环境,由 top 的输出结果我们也发现, 系统同时间有非常多的程序在运行中,叧是大部分的程序都在休眠 (sleeping) 状态而已。如果所有的程序同时被唤醒,那 CPU 应该要先处理那个程序呢?

具有优先级的程序队列图:

我们知道 CPU 一秒钟可以运作多达数 G 的微指令次数,透过核心的 CPU 排程可以让各程序被 CPU 所切

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值