🌈欢迎来到Python专栏
🙋🏾♀️作者介绍:前PLA队员 目前是一名普通本科大三的软件工程专业学生
🌏IP坐标:湖北武汉
🍉 目前技术栈:C/C++、Linux系统编程、计算机网络、数据结构、Mysql、Python(目前在学)
🍇 博客介绍:通过分享学习过程,加深知识点的掌握,也希望通过平台能认识更多同僚,如果觉得文章有帮助,请您动动发财手点点赞,本人水平有限,有不足之处欢迎大家扶正~
🍓 最后送大家一句话共勉:知不足而奋进,望远山而前行。愿大家都能早日进大厂实现财富自由~
————————————————
多进程编程
- 1.进程及进程状态介绍
- 1.1进程
- 1.2进程状态
- 2.Linux下 进程管理
- 3.3 进程、线程对比
- 4.进程相关使用
1.进程及进程状态介绍
1.1进程
-
程序:例如 xxx.py 这是程序,是一个静态的
-
进程:一个程序运行起来后,代码+用到的资源称之为进程,它是操作系统分配资源的基本单元。
1.2进程状态
工作中,任务数往往大于 cpu 的核数,即一定有一些任务正在执行,而另外一些任务在等待 cpu 进行执行,因此导致了有了不同的状态
• 就绪态:运行的条件都已经满足,正在等在 cpu 执行
• 执行态:cpu 正在执行其功能
• 等待态:等待某些条件满足,例如一个程序 sleep 了,此时就处于等待态
top
ps
R 状态 运行S 状态 睡眠
看到 R 状态是两次采样之间的一个时间片变化分析计算
cat /proc/cpuinfo 查看 Linux 的 cpu 的核数
2.Linux下 进程管理
- 启动进程:手工启动 调度启动
备注:
进程 process:是 os 的最小单元 os 会为每个进程分配大小为 4g 的虚拟内存空间,其中
1g 给内核空间 3g 给用户空间{代码区 数据区 堆栈区}
cat /proc/cpuinfo 查看 CPU 个数
ps 查看活动进程 ps –aux 查看所有的进程 ps-aux| grep 'aa'查找指定(aa)进程 ps –elf 可以显示父子进程关系进程状态:执行 就绪 等待状态
ps -aux 看%cpu(cpu 使用量) %mem(内存使用量) stat 状态{S 睡眠 T 暂停 R 运行 Z僵尸}
top 显示前 20 条进程,动态的改变,按 q 退出
第一行分别显示:
平均负载(load average),一般对于单个 cpu 来说,负载在 0~1.00 之间是正常的,超过 1.00 须引起注意。在多核 cpu 中,系统平均负载不应该高于 cpu 核心的总数。
第二行分别显示:
第三行
第四行
第五行:
buffers 与 cached 区别:buffers 指的是块设备的读写缓冲区,cached 指的
是文件系统本身的页面缓存。他们都是 Linux 系统底层的机制,为了加速对磁盘的访问。
然后下面就是和 ps 相仿的各进程情况列表了
第六行:
PID 进程号
USER 运行用户PR
优先级,PR(Priority)优先级
NI 任务 nice 值
VIRT 进程使用的虚拟内存总量,单位 kb。VIRT=SWAP+RES
RES 物理内存用量
SHR 共享内存用量
S 该进程的状态。其中 S 代表休眠状态;D 代表不可中断的休眠状态;R 代表运行状态;Z 代表僵死状态;T 代表停止或跟踪状态
%CPU 该进程自最近一次刷新以来所占用的 CPU 时间和总时间的百分比
%MEM 该进程占用的物理内存占总内存的百分比
TIME+ 累计 cpu 占用时间
COMMAND 该进程的命令名称,如果一行显示不下,则会进行截取。内存中的进程会有一个完整的命令行
3.3 进程、线程对比
功能
• 进程,能够完成多任务,比如 在一台电脑上能够同时运行多个 QQ
• 线程,能够完成多任务,比如 一个 QQ 中的多个聊天窗口
定义的不同
• 进程是系统进行资源分配和调度的一个独立单位.
• 线程是进程的一个实体,是 CPU 调度和分派的基本单位,它是比进程更小的能独
立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源.
区别
• 一个程序至少有一个进程,一个进程至少有一个线程.
• 线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高。
• 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提
高了程序的运行效率
线线程不能够独立执行,必须依存在进程中
优缺点
线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;
而进程正相反
4.进程相关使用
- 进程创建:
#!/usr/bin/python
# author X_Dragon
# E-mail:3270895551@qq.com
# @Time : 2023/11/21 11:03
from multiprocessing import Process
import time
import os
# 子进程运行代码
def run_proc():while True:print('-----2-----')print("进程ID:", os.getpid())time.sleep(1)
if __name__ == '__main__':p=Process(target=run_proc) # run_proc 传递时不可以加括号p.start()while True:print('----1-----')print("进程ID:", os.getpid())time.sleep(1)
- 2.僵尸进程制作
#!/usr/bin/python
# author X_Dragon
# E-mail:3270895551@qq.com
# @Time : 2023/11/21 11:21
import os
from multiprocessing import Process
import timedef run_proc():print('我是子进程 pid={},ppid={}'.format(os.getpid(),os.getppid()))# 这段代码中的format()函数用于将字符串中的占位符替换为指定的值。在这个例子中,# {}是一个占位符,它将被format()函数替换为os.getpid()和os.getppid()的返回值。print('子进程结束')
if __name__ == '__main__':child=Process(target=run_proc)child.start()print('我是父进程,我的pid={},ppid={}'.format(os.getpid(),os.getppid()))
- 3.进程传参
#!/usr/bin/python
# author X_Dragon
# E-mail:3270895551@qq.com
# @Time : 2023/11/22 10:17
from multiprocessing import Process
import os
import time
def run_pro(name,age,**kwargs):for i in range(10):print('子进程{} {} ,{}'.format(name, age, kwargs))time.sleep(0.2)
if __name__ == '__main__':p=Process(target=run_pro,args=("wangwu",10),kwargs={'408':120})p.start()time.sleep(1)p.terminate() # 给子进程发信号杀掉它p.join() # 一直等子进程,子进程结束,资源会被回收print('我是父进程')
- 4.进程间对于全局变量的使用
#!/usr/bin/python
# author X_Dragon
# E-mail:3270895551@qq.com
# @Time : 2023/11/22 10:25
from multiprocessing import Process
import os
import timenums=[11,22]
def work1():print('I am work1,{}'.format(os.getpid()))nums.append(33)time.sleep(2)print('work1 {}'.format(nums))
def work2():print('I am work2,{}'.format(os.getpid()))print(nums)
if __name__ == '__main__':p=Process(target=work1)p.start()time.sleep(1)# nums.append(44)print('I am parent,{}'.format(nums))p.join()p = Process(target=work2)p.start()p.join()print(nums)
"""在多进程的环境中,
每个进程都有自己独立的地址空间,全局变量也在这个地址空间中。
因此,每个进程都有一份自己的全局变量副本,它们互相独立。
当一个进程修改自己的全局变量时,不会影响其他进程的全局变量。
这是因为进程之间是相互隔离的,它们不共享内存空间
"""
== 在多进程的环境中,
每个进程都有自己独立的地址空间,全局变量也在这个地址空间中。
因此,每个进程都有一份自己的全局变量副本,它们互相独立。
当一个进程修改自己的全局变量时,不会影响其他进程的全局变量。
这是因为进程之间是相互隔离的,它们不共享内存空间 ==
- 5.使用使用queue在进程中通信
#!/usr/bin/python
# author X_Dragon
# E-mail:3270895551@qq.com
# @Time : 2023/11/22 10:36from multiprocessing import Process, Queue
import time
def writer(q):for value in ['A', 'B', 'C']:print('Put %s to queue...' % value)q.put(value)time.sleep(1)def reader(q:Queue):while True:if not q.empty():value = q.get(True)print('Get %s from queue.' % value)time.sleep(2)else:breakif __name__ == '__main__':q=Queue(10)pw=Process(target=writer,args=(q,)) #一个元素必须加逗号,才是元组pr=Process(target=reader,args=(q,))pw.start()time.sleep(1)pr.start()pw.join()pr.join()
- 6.进程池使用
#!/usr/bin/python
# author X_Dragon
# E-mail:3270895551@qq.com
# @Time : 2023/11/22 10:40
from multiprocessing.pool import Poolimport os, time, randomdef worker(msg):star_time=time.time()# print("%s开始执行,线程号:%d" % msg,os.getpid())print("%s开始执行,线程号:%d" % (msg, os.getpid()))time.sleep(random.random()*2)end_time=time.time()# print("%s执行完毕,线程号:%d,线程执行事件为%0.2f" % msg,os.getpid(),star_time-end_time)print("%s执行完毕,线程号:%d,线程执行事件为%0.2f" % (msg, os.getpid(), end_time - star_time))
if __name__ == '__main__':po=Pool(10)for i in range(10):# 每次循环都会用空闲出来的子进程去调用目标po.apply_async(worker,(i,))print("--------start----------")po.close()po.join()print("---------end------------")
本篇到这~觉得有用麻烦您动动发财小手点点赞