进程管理

Processes 理论

什么是 进程、子进程、线程、协程

进程

  • 进程是操作系统的 systemd 父进程所生成
  • 进程是运行中程序的一个副本,是被载入内存的一个指令合集,是资源分配的单位
  • 进程出现问题,其它进程不会收到影响

子进程

  • 子进程由父进程生成
  • 子进程最初是和父进程在一起 并共用同一块内存空间,当子进程发生数据更新时 会给子进程分配一块独立的内存空间 并将更新的内容写入其中 最后再从父进程中独立出来

线程

  • 线程就相当于进程中的员工,每个进程至少有一个线程,进程和线程间是包含关系 即进程中一定包含线程
  • 进程中的线程出现问题,其它线程也会收到影响

协程

  • 协程不一定每个进程中都有,可以将协程理解为一个小函数
  • 而协程是由程序员写程序来决定的

LRU 算法

  • Least Recently Used 近期最少使用算法(喜新厌旧),释放内存

范例

#假设序列为 4 3 4 2 3 1 4 2, 物理块有3个,则:
第1轮 4调入内存 4
第2轮 3调入内存 3 4
第3轮 4调入内存 4 3
第4轮 2调入内存 2 4 3
第5轮 3调入内存 3 2 4
第6轮 1调入内存 1 3 2
第7轮 4调入内存 4 1 3
第8轮 2调入内存 2 4 1

进程间通信方式

同一主机间

  • 管道 Pipes
    • 特点:fifo 单向传输
  • 命名管道 Named Pipes
    • 管道文件
    • 特点:fifo 单向传输
  • 套接字文件 Socket File
    • s 开头,find / -type s
    • 特点:双向传输
  • 共享内存 shared memory
    • 共享内存
    • free 命令中 shared 那一列
  • 内存映射文件 Memory-Mapped Files
    • 将文件中的一段数据映射到物理内存,多个进程共享这片内存
  • 信号 Signal
    • kill命令发信号、trap捕捉信号
  • 信号量 Semaphore
    • 一种计数器
  • 锁 Lock
    • 对资源上锁,如果资源已被某进程锁住,则其它进程想修改甚至读取这些资源,都将被阻塞,直到锁被打开

不同主机间

  • 远程过程调用 PRC Remote Procedure Call

  • 消息队列 MQ Message Queue

    • Kafka,RabbitMQ,ActiveMQ
    • 生产者和消费者
  • 套接字 Socket

    • IP + Port

命名管道范例

  • mkfifo 创建命名管道文件
  • 管道文件可以实现进程间通信
[root@8 ~]# mkfifo test.fifo
[root@8 ~]# ll
total 0
prw-r--r-- 1 root root 0 Dec 20 12:34 test.fifo
[root@8 ~]# echo $BASHPID
2623
[root@8 ~]# cat > test.fifo 
abc

[root@8 ~]# echo $BASHPID
2649
[root@8 ~]# cat test.fifo 
abc

进程的状态

运行态 R Running

ready 就绪态

sleep 睡眠态

  • 分为两种,可中断:interruptable(bc命令),不可中断:uninterruptable

stopped 停止态

  • 暂停于内存,但不会被调度,除非手动启动

zombie 僵尸态

  • 结束进程,父进程结束前,子进程不关闭
  • 僵尸进程基本上不占用内存和CPU,对系统性能基本上不受影响
  • **僵尸进程的产生原因:**子进程被杀死前 如果父进程处于停止态 那么父进程将无法回收被杀死的子进程 从而子进程就成为了僵尸态
  • 当父进程恢复或被杀死后 将会回收僵尸态的子进程(但父进程能不能杀死也要看情况,如systemd进程被杀死系统将崩溃,其实僵尸进程不杀死也没事,就看着别扭)
#杀死僵尸进程
kill -9 pid

进程优先级

  • 内核将进程划分成 0~139 140个优先级;优先级数值越小 优先级越高
    • 0~99 为系统内部优先级,专供实时进程使用
    • 100139 为普通进程优先级;对应 nice值的 -2019
    • 通常终端可见的只有NICE值;像一般的空闲内核线程NICE值都为-20;默认创建进程的优先级为0 也可以在-20到+20间指定
  • 各有140个运行队列和过期队列,一个cpu的时间片进程没有执行完毕则放入到过期队列中…
  • 访问优先级的好处是可以让系统进程优先运行,并且优先级的时间复杂度为O(1) 即不会收到进程数量的影响而带来运行效率的降低

进程分类

按前后台分类:

守护进程

  • daemon,在系统引导过程中启动的进程,和终端无关进程

前台进程

  • 跟终端相关,通过终端启动的进程

按进程资源使用的分类:

CPU密集型

  • 一般都是非交互场合(压缩解压缩)

IO密集型

  • 一般都是交互频繁的场合(浏览网站)

按操作系统分类:

协作式多任务

  • 早期 windows 系统使用,即一个任务得到了 CPU 时间,除非它自己放弃使用CPU ,否则将完全霸占 CPU ,所以任务之间需要协作——使用一段时间的 CPU ,主动放弃使用

抢占式多任务

  • Linux内核,CPU的总控制权在操作系统手中,操作系统会轮流询问每一个任务是否需要使用 CPU ,需要使用的话就让它用,不过在一定时间后,操作系统会剥夺当前任务的 CPU 使用权,把它排在询问队列的最后,再去询问下一个任务(上下文切换)

SIGNAL

  • man 7 signal
  • 常见信号:
0)          #对进程进行健康性检查(健康则$?结果为0,反之则为1),但结果并不严谨 因为进程只要存在 它就认为进程是健康的 如:进程已经成为僵尸态 而$?的返回值依旧为0
1) SIGHUP   #无须关闭进程而让其重读配置文件
2) SIGINT   #中止正在运行的进程;相当于Ctrl+c
3) SIGQUIT  #相当于ctrl+\
9) SIGKILL  #强制杀死正在运行的进程(trap无法捕获此信号)
15) SIGTERM #终止正在运行的进程,默认信号(有时候比9信号更好使)
18) SIGCONT #继续运行
19) SIGSTOP #后台休眠(变成停止态 相当于对程序CTRL+Z)

IO调度算法

#查看系统默认的调度算法,一般都不用修改 除非特殊场合做特定的优化
[root@ubuntu1804 ~]#cat /sys/block/sda/queue/scheduler 
noop deadline [cfq] 
[root@centos8 ~]#cat /sys/block/sda/queue/scheduler 
[mq-deadline] kyber bfq none
[root@centos7 ~]#cat /sys/block/sda/queue/scheduler
noop [deadline] cfq 
[root@centos6 ~]#cat /sys/block/sda/queue/scheduler
noop anticipatory deadline [cfq]

CPU 缓存

  • 假如CPU有多核心,那么每个核心都有独立的一级、二级缓存,但三级缓存是所有核心共同拥有的

内核中查看进程相关信息

查看进程中的线程

cat /proc/PID/status |grep -i threads

#范例
[root@centos ~]# cat /proc/867/status | grep -i threads
Threads:	4 #4表示进程+线程的数量,即1进程+3线程

找到进程所使用的二进制程序

ls -l /proc/PID/exe

#范例
[root@centos ~]# ll /proc/1063/exe 
lrwxrwxrwx 1 root root 0 Nov 18 00:43 /proc/1063/exe -> /usr/sbin/openvpn

作业管理

作业类型

  • **前台作业:**通过终端启动,且启动后一直占据终端
  • **后台作业:**可通过终端启动,但启动后即转入后台运行(释放终端)

让作业运行于后台

  • 运行中的作业: Ctrl+z
  • 尚未启动的作业: COMMAND &
  • **注意:**后台作业虽然被送往后台运行,但其依然与终端相关;退出终端,将关闭后台作业。如果希望送往后台后,剥离与终端的关系可以使用:screen、tmux等工具

查看当前终端所有作业

  • jobs(只能看到和当前终端相关的作业,如:/dev/pts/0只能看到/dev/pts/0的作业)

作业控制

fg [[%]JOB_NUM] #把指定的后台作业调回前台
bg [[%]JOB_NUM] #让送往后台的作业在后台继续运行
kill [%JOB_NUM] #终止指定的作业

并行运行

  • 利用后台执行,实现并行功能,即同时运行多个进程,提高效率

方法1

cat all.sh
f1.sh&
f2.sh&
f3.sh&

方法2

(f1.sh&);(f2.sh&);(f3.sh&)

方法3

f1.sh&f2.sh&f3.sh&

范例:多组命令实现并行

[root@centos8 ~]#{ ping -c3 127.1; ping 127.2; }& { ping -c3 127.3 ;ping 127.4; }&

范例:脚本中使用并行运行

[root@centos8 ~]#cat scanhost.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2020-01-17
#FileName: scanhost.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
NET=10.0.0
for i in {1..254};do
   {
   ping -c1 -W1 ${NET}.${i} &> /dev/null && echo ${NET}.${i} is up || echo
${NET}.${i} is down
   }&
done
wait

----------------------------------------------------------------------------------------
#执行
[root@centos8 ~]#bash scanhost.sh
10.0.0.7 is up
10.0.0.1 is up
10.0.0.2 is up
10.0.0.6 is up
10.0.0.8 is up
10.0.0.3 is down
10.0.0.5 is down
10.0.0.29 is down
10.0.0.14 is down
10.0.0.15 is down
10.0.0.10 is down
10.0.0.23 is down
10.0.0.12 is down
......
10.0.0.245 is down
10.0.0.246 is down
10.0.0.240 is down