Linux-进程、线程、协程

文中代码示例: python

进程

服务器进程管理:
进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源(CPU时间片、内存等资源),进程是资源分配的最小单位。
进程之间通信:
管道(Pipe)、命名管道(FIFO)、消息队列(Message Queue) 、信号量(Semaphore) 、共享内存(Shared Memory);套接字(Socket)。

在这里插入图片描述

from multiprocessing import Process
import time,os

def process(text):
    print('当前进程:',os.getpid())
    print('当前父进程:',os.getppid())
    print('我是子进程')
    time.sleep(2)
    print('子进程结束')

if __name__ == '__main__':
    print(f'我的进程: {os.getpid()}')
    print(f'我的父进程: {os.getppid()}')
    pro = Process(target=process, args=('hello world',))
    pro.start()
    pro.join()
    print('父进程结束')

线程

线程,又称为轻量级进程(Lightweight Process,LWP),是操作系统调度(CPU调度)执行的最小单位。

在这里插入图片描述

from threading import Thread,current_thread
import time
def thread(text):
    print('我是:',current_thread.__name__)
    print('子进程开始')
    time.sleep(2)
    print('子进程结束')

if __name__ == '__main__':
    print('我是父进程')
    t = Thread(target=thread, args=('hello world',))
    t.start()
    t.join()
    print('父进程结束')

线程进程的区别

【区别】:
调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位;
并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行;
拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。进程所维护的是程序所包含的资源(静态资源), 如:地址空间,打开的文件句柄集,文件系统状态,信号处理handler等;线程所维护的运行相关的资源(动态资源),如:运行栈,调度相关的控制信息,待处理的信号集等;
系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。但是进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个进程死掉就等于所有的线程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。
【联系】:
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;
资源分配给进程,同一进程的所有线程共享该进程的所有资源;
处理机分给线程,即真正在处理机上运行的是线程;
线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

协程

在这里插入图片描述

协程,是一种比线程更加轻量级的存在,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。

极高的执行效率:因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显;

不需要多线程的锁机制:因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

def make(num):
    for i in range(num):
        yield f'正在制作第{i+1}个包子'

def eat(num):
    for i in range(num):
        yield f'正在享用第{i+1}个包子'

if __name__ == '__main__':
    m = make(10)
    e = eat(10)
    try:
        while True:
            print(m.__next__())
            print(e.__next__())
    except StopIteration as e:
        print('任务完成')

亲缘性

使用CPU亲缘性的好处:设置CPU亲缘性是为了防止进程/线程在CPU的核上频繁切换,从而避免因切换带来的CPU的L1/L2 cache失效,cache失效会降低程序的性能。

进程状态

Linux进程状态:R (TASK_RUNNING),可执行状态&运行状态(在run_queue队列里的状态)

Linux进程状态:S (TASK_INTERRUPTIBLE),可中断的睡眠状态, 可处理signal

Linux进程状态:D (TASK_UNINTERRUPTIBLE),不可中断的睡眠状态, 可处理signal, 有延迟

Linux进程状态:T (TASK_STOPPED or TASK_TRACED),暂停状态或跟踪状态, 不可处理signal, 因为根本没有时间片运行代码

Linux进程状态:Z (TASK_DEAD - EXIT_ZOMBIE),退出状态,进程成为僵尸进程。不可被kill, 即不响应任务信号, 无法用SIGKILL杀死

状态后缀标识

<:优先级高的进程

N:优先级低的进程

L:有些页被锁进内存

s:进程的领导者(在它之下有子进程)

l:ismulti-threaded (using CLONE_THREAD, like NPTL pthreads do)

+:位于后台的进程组

Linux 查看进程状态

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

杀死僵尸进程

僵尸进程指已经结束的进程,父进程没有调用wait pid 将他结束,可以通过杀死其父进程的方式杀死僵尸进程,ps -ef |grep

常用命令

1、ps

ps是Linux 中最基础的浏览系统中的进程的命令。能列出系统中运行的进程,包括进程号、命令、CPU使用量、内存使用量等。下述选项可以得到更多有用的消息。

ps -ef |grep - 列出需要进程
ps -aux - 显示进程信息,包括无终端的(x)和针对用户(u)的进程:如USER, PID, %CPU, %MEM等

在这里插入图片描述

2、top/htop

操作方法: 略
参数了解:
第一行:启动时间、登录用户、cpu负载
第二行:总进程数、运行进程、休眠进程、停止进程、僵尸进程
第三行:
us:用户态进程,运行(未调整优先级的) 用户进程的CPU时间
sy:内核态进程,运行内核进程的CPU时间
ni:进程优先级运行已调整优先级的用户进程的CPU时间
wa:IO wait,用于等待IO完成的CPU时间
hi:处理硬件中断的CPU时间
si:处理软件中断的CPU时间
st:这个虚拟机被VMM偷去的CPU时间(如果当前处于一个VMM下的guestos,实际上VMM也是要消耗一部分CPU处理时间)。

在这里插入图片描述
在这里插入图片描述
3、lsof

lsof -i[46] [protocol][@hostname|hostaddr][:service|port]

lsof -i:3306 # 查看哪个进程占用了3306端口
lsof -i:mysql # 查看mysql服务
lsof -i TCP # 查看TCP连接,UDP同理
在这里插入图片描述
lsof -u mysql # 查看用户打开了什么,^mysql 取反
在这里插入图片描述
lsof -p 1663 # 查看pid 的内容
在这里插入图片描述
lsof /var/lib/mysql/mysql.sock # 显示与目录或文件交互的信息
在这里插入图片描述
4、ipcs
在这里插入图片描述

修改系统的nice值

查看进程优先级
在这里插入图片描述
pri 为进程的优先级,数值越小,优先级越高
nice 不是优先级,而是优先级的修正参数,当nice值为负数,说明优先级会变得更高
优先级 = 优先级 + nice值

nice命令

设置nice 值,在进程启动时执行
nice -n -10 systemctl start mysql

renice命令

设置nice值,在进程运行中执行
renice -5 10000 # 将pid 为10000的进程nice值设置为-5 如果优先级为80 那么实际就是78

进程调度策略

在这里插入图片描述

  • SCHED_OTHER,分时调度策略
  • SCHED_FIFO,实时调度策略,先到先服务
  • SCHED_RR,实时调度策略,时间片轮转

信号

[1] SIGHUP 重新加载配置 PID不变
[2] SIGINT 键盘中断^C
[3] SIGQUIT 键盘退出
[9] SIGKILL 强制终止
[15] SIGTERM 终止(正常结束),缺省信号
[18] SIGCONT 继续
[19] SIGSTOP 停止
[20] SIGTSTP 暂停^Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值