Linux 进程管理

这一篇主要记录一些进程管理的命令,以及一小部分概念的笔记

线程是调度的基本单位,进程是资源拥有的基本单位

一、常见进程管理软件

jobs 查看后台工作状态

  • 进程运行中,按Ctrl+z 会导致进程停止并且进入后台等待
  • 通过&将进程丢到后台运行

jobs -l  可以查看当前的job

fg 将停止的工作提到前台继续运行

会话结束后,fg的任务也会中断

fg %1   将编号1的job到前台运行

bg 将停止的工作放到后台继续运行

会话结束后,bg的任务也会中断

bg %1  将1号job放到后台运行和&一样

kill

kill -l 查看可用的single

常用 single
    -0 检查进程是否正常运行,$? 0正常,大于0 就是不正常,会返回异常
    -1 SIGHUP:重新读取一次参数的配置文件 (类似 reload)
    -2 SIGINT:代表与由键盘输入 [ctrl]-c 同样的动作
    -9 SIGKILL:立刻强制删除一个工作
    -15 SIGTERM:以正常的进程方式终止一项工作

常用的方式:
kill -9 %1  通过kill 强行 关闭jobs
kill -15 %1 以正常的进程方式终止一项工作,告诉进程要结束了
kill -9 pid 强行结束进程(慎用!)

注意:结束工作请加%,避免强行关闭系统pid导致系统挂掉

pwdx 查看进程对应的工作目录

可以结合netstat 使用,用来查找进程的工作目录

netstat -anlp|grep 端口
pwdx pid

lsof 查看进程与文件的关联关系

lsof -p pid         # 查看指定进程用了哪些文件
lsof filepath       # 查看文件被哪些进程占用
lsof +d filepath    # 查看目录中被进程打开的文件
lsof -u username    # 查看某个用户的进程打开的文件
lsof -p pid -Pn     # 查看进程的socket
lsof |grep delete   # 查看被删除仍占用的文件和进程,这个全局的比较慢

fuser 通过文件或者文件系统找出正在使用该文件的进程

貌似没有lsof好用

fuser -mvu /proc  # 查看使用这个目录的进程和文件系统顶层情况
fuser -vu /proc   # 查看占用的进程的进程号和命令

pidstat 查看进程的状态

可以快速的找到读写高的进程,默认是显示CPU,非常好用、非常强大,简单截取了一部分

man pidstat
-C comm
    Display only tasks whose command name includes the string comm.  This string can be a regular expression.

-d     Report I/O statistics (kernels 2.6.20 and later only).  The following values may be displayed:
    UID    The real user identification number of the task being monitored.
    USER    The name of the real user owning the task being monitored.
    PID     The identification number of the task being monitored.
    kB_rd/s    Number of kilobytes the task has caused to be read from disk per second.
    kB_wr/s    Number of kilobytes the task has caused, or shall cause to be written to disk per second.
    kB_ccwr/s    Number  of  kilobytes  whose writing to disk has been cancelled by the task.This may occur when the task truncates some dirty pagecache. In this case, some IO which another task has been accounted for will not be happening.
    
-p pid
    
-r     Report page faults and memory utilization.

帮助文档用例:

# 每隔两秒显示系统中每个活动任务的CPU报告,统计5次
pidstat 2 5

# 每隔两秒钟显示PID 为 1643的页面故障和内存统计信息报告,统计5次
pidstat -r -p 1643 2 5

# 显示所有进程中包含"fox" 或 "bird"的进程的全局页面故障和内存统计信息
pidstat -C "fox|bird" -r -p ALL

# 每5秒打印一次进程IO情况,打印5次 
pid -d 5 5

全局页故障(global page faults)是指进程在访问内存时,所需的页面不在物理内存中,而是存储在磁盘上。当进程需要访问该页面时,操作系统会将该页面从磁盘加载到物理内存中,从而导致全局页故障。

nohub  在脱机或注销系统后,还能够让工作继续进行

注意: 如果是执行远程的nuhup 可能会出现预期外的结果,由于远程子shell结束而导致nohup进程结束

解决办法是 将需要放后台的命令结果重定向到/dev/null 进程会被system托管,例如:

 sudo nohup tcpdump -i ens3 -w ens3.pcap >/dev/null 2>&1  &

pstree

显示进程树,不常用

pstree -p pid

二、Linux进程

Task 是 Linux 中的进程描述符,用于表示一个正在运行的进程。Task 结构体包含了进程的所有信息,如进程状态、调度信息、进程间通信状况、内存地址等。每个进程都有一个对应的 task 结构体。在 Linux 内核中,task 结构体定义在包含在内核源文件 include/linux/sched.h 中。

Task 结构体的主要信息有:

  • 进程状态:记录进程在等待、运行或死锁等状态
  • 调度信息:记录由哪个调度函数调度以及如何调度
  • 进程通信状况:记录进程之间的通信方式
  • 进程树关系:记录进程在进程树中的位置,方便父子进程之间的查找
  • 时间信息:用于计算进程执行的时间,以便分配 CPU 时间片
  • 进程标识:决定进程的归属和优先级
  • 打开文件信息:记录进程打开的文件描述符
  • 进程上下文和内核上下文:用于存储进程在用户态和内核态之间的切换信息
  • 处理器上下文:记录进程在不同的处理器之间切换时的状态信息
  • 内存信息:记录进程的内存使用情况

程序与进程

程序

存储在磁盘中,以可见文件状态存在

进程

程序执行后,执行者的权限与属性、程序的程序代码与所需数据等都会被加载内存中,操作系统并给予这个内存内的单元一个标识符 (PID),可以说,进程就是一个正在运行中的程序

实时进程(Real-time Process)

实时进程是指在规定时间内必须完成特定任务的进程。

实时进程对系统的实时性能要求较高,通常用于实时控制系统、硬实时任务等。实时进程的优先级范围为0-99,优先级越高,表示对实时性能要求越严格。实时进程的优先级受到实时调度算法的影响,确保实时任务在规定时间内完成。

后台进程(Background Process)

后台进程是在后台执行的进程,通常不需要用户干预,如系统服务、定时任务等。

后台进程的优先级相对较低,主要用于执行一些不需要立即响应的任务。后台进程的优先级受到普通进程调度算法的影响,与其他普通进程竞争CPU资源。

普通进程(Normal Process)

普通进程是日常使用中常见的进程,如用户程序、系统服务等。

普通进程的优先级范围为100-139,优先级越高,表示对CPU资源的需求越迫切。普通进程的优先级受到nice值和抢占优先级的影响,在多个普通进程同时运行时,操作系统根据进程的优先级进行调度。

top

top 状态
    R (Running):该程序正在运作中;
    S (Sleep):该程序目前正在睡眠状态(idle),但可以被唤醒(signal)。
    D :不可被唤醒的睡眠状态,通常这支程序可能在等待 I/O 的情况(ex>打印)
    T :停止状态(stop),可能是在工作控制(背景暂停)或除错 (traced) 状态;
    Z (Zombie):僵尸状态,进程已经终止但却无法被移除至内存外

僵尸进程,需要通过父进程来排查产生原因,从根本上解决问题,如果僵尸进程被systemd托管了,一般只能通过重启来清除了。

注意:cron 定时任务如果有大量的输出没有被重定向,会导致系统出现senb mail 的僵尸进程

命令行:
top -b -n 2 -d 1 > /tmp/top.txt    将top 1秒共计两次刷新结果写入文件

动态界面:
    h 查看帮助
    H 将进程切换到线程
    M 内存排序
    R 进程号排序
    i 展示非空闲进程
    e 切换动态内容内存的显示单位    
    E 切换前面4-5内存显示单位
    f 设置显示列表
    0 隐藏0项的数据
    1 查看CPU核数
    2/3 查看NUMA节点,再输入节点可以过滤对应节点的数据

程序优先级

Linux 给予进程一个所谓的 优先执行序 (priority, PRI),这个 PRI 值越低代表越优先的意思

不过这个 PRI 值是由核心动态调整的,用户无法直接调整 PRI值

nice 

PRI(new) = PRI(old) + nice

  • 当 nice 值为负值时,那么该进程就会降低 PRI 值,亦即会变的较优先被处理
  • nice 值可调整的范围为 -20 ~ 19 
  • root 可随意调整自己或他人进程的 Nice 值,且范围为 -20 ~ 19
  • 一般使用者仅可调整自己进程的 Nice 值,且范围仅为 0 ~ 19 (避免一般用户抢占系统资源)
  • 一般使用者仅可将 nice 值越调越高,例如本来 nice 为 5 ,则未来仅能调整到大于 5

配置nice的方式:

  • 一开始执行程序就立即给予一个特定的 nice 值:用 nice 指令
  • 调整某个已经存在的 PID 的 nice 值:用 renice 指令

进程优先级(Process Priority)

进程优先级是操作系统在调度进程时判断进程是否获得CPU资源的依据之一。优先级越高,进程在竞争CPU资源时具有更高的优先级。

实时优先级(Real-time Priority)

实时优先级用于区分实时进程和非实时进程。实时进程具有较高的优先级,以确保实时任务在规定时间内完成。

抢占优先级(Preemption Priority)

抢占优先级用于表示进程在抢占式调度中的优先级。当进程在执行过程中遇到更高优先级的进程时,操作系统会中断当前进程并切换到高优先级进程。

动态优先级

动态优先级用于表示进程在运行过程中的优先级。它受到抢占优先级、实时优先级和nice值的影响,可以通过调整这些参数来改变动态优先级。

进程资源限制

cgroup(控制组)

cgroup 是一种虚拟的资源管理单元,用于将相关资源(如 CPU、内存、设备 IO 等)组合在一起。管理员可以对组内的资源进行集中管理和分配。

cgroup 层次结构:根 cgroup 是所有 cgroup 的父节点,子 cgroup 是根 cgroup 下的第一个层级。子 cgroup 可以根据需要继续创建孙 cgroup。这种层次结构有助于实现对资源的逐级分配和管理。

资源控制:cgroup 允许管理员为组内的进程设置 CPU、内存等资源的限制。这样,可以确保资源在组内合理分配,避免进程过度消耗系统资源。

操作与管理:cgroup 的操作与管理主要包括创建、删除、修改资源限制等。这些操作可以通过 cgcreate、cgdelete、cgexec 等命令实现。

/sys/fs/cgroup 可以看到cgroup的子系统,不同资源的具体管理工作由相应的Cgroup子系统(Subsysytem)来实现,针对不同的资源限制,将限制策略关联到不同的子系统即可;

演示:通过cgroup控制进程CPU资源,发现创建的目录删不掉了。。。重启后就没了。

cd /sys/fs/cgroup/cpu
# 创建一个CPU的cgroup子系统,会自动补全文件
mkdir cpudemo && cd cpudemo
# 执行消耗CPU的进程
echo '234 ^ 12903123'|bc &>2 /dev/null
# 将上述进程的进程号写入到限制的进程清单内
cat bc_pid > cgroup.procs
# 通过cpu.cfs_quota_us 限制 cgroup.procs 里面的CPU进程资源
cpu.cfs_quota_us     cgroup.procs进程能占用的时间片
cpu.cfs_period_us    一个CPU的时间片
# 注意最小都得1000否则会报错bash: echo: write error: Invalid argument
echo '1000' > cpu.cfs_quota_us
# 由于cpu.cfs_period_us 是100000 所以这个进程只能占用一个CPU的1%
# cpu.cfs_quota_us 实测大于cpu.cfs_period_us  也只能用1个CPU,应该被其他配置限制了

namespace(命名空间)

命名空间是一种隔离机制,用于将不同类型的资源(如进程、文件、网络等)与底层操作系统隔离。通过命名空间,可以实现不同进程之间的资源隔离和互斥访问

命名空间作用:命名空间的主要作用是实现资源隔离,确保不同进程之间的资源访问不会相互干扰。此外,命名空间还可以实现进程间的互斥操作,防止进程非法访问受限制的资源。

可隔离资源
  • IPC         System V IPC 和 POSIX 消息队列
  • Network     网络设备、网络协议栈、网络端口等
  • PID         进程
  • Mount       挂载点
  • UTS         主机名和域名
  • USR         用户和用户组
常见操作
查看当前的namespace
    lsnt -t <type> 
查看进程的namespace
    ls -la /proc/pid/ns
进入namespace执行命令
    docker inspect docker_id|grep -i pid
    nsenter -t pid -n ip addr 
    nsenter -t 23510 --mount --uts --ipc --net --pid
新建namespace的方式

unshare 该系统调用可以将调用进程移动到新的namespace

        unshare -fn sleep 120 

        int unshare(int flags)

clone 在创建新进程的系统调用时,可以通过flags参数指定需要新建的namespace类型

        int clone(int (*fn)(void *),void *child_stack,int flags,void *arg)

setns 该系统调用可以让调用进程加入某个namespace

        int setns(int fd,int nstype)

docker 是起了一个新的进程,然后fork了一个namespace

后台进程

nohup 和 & 在 Linux 中都用于将命令置于后台执行

使用场景

& 通常用于在后台执行不需要与父进程交互的命令,例如长时间运行的计算任务或守护进程

nohup 通常用于在后台执行需要与父进程交互的命令,例如需要读取用户输入或显示输出的命令

区别

1、输出

& 在后台执行命令时,会将命令的标准输出和标准错误重定向到 /dev/null

nohup 在后台执行命令时,不会将命令的标准输出和标准错误重定向到 /dev/null ,会显示打印

2、退出

& 在后台执行命令时,如果父进程退出,子进程也会收到信号并退出

nohup 在后台执行命令时,即使父进程退出,子进程也不会收到信号并退出

3、都是fork 子进程,但是

& 子进程继承了父进程的资源,包括环境变量、打开的文件句柄等,但子进程与父进程是相互独立的 (记忆可以类比软链接)

nohup 子进程与父进程是共用的 (记忆可以类比硬链接)

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值