当前位置: 首页 > backend >正文

python多进程

目录

(1)如何创建

(2)join函数

(3)锁

(4)管道

(5)队列

(6)多进程中普通全局变量无法共享

(7)进程间数据共享

1.使用multiprocessing.Queue() 

2.使用multiprocessing.Value

3.使用multiprocessing.Array

4.使用multiprocessing.Manager().list或dict

(8)守护进程

(9)进程信号量

(10)进程间通信


Python多进程利用multiprocessing模块,创建独立进程并行计算,突破GIL限制,适合CPU密集型任务。

(1)如何创建

用multiprocessing模块

import os
import multiprocessing
import timedef info(title):print(title)print(__name__)print("father ppid", os.getppid())   # 父进程idprint("self pid", os.getpid())       # 子进程idprint("-----------")print("执行被调用函数中.......")time.sleep(5)if  __name__ == "__main__":info("hello")#创建多进程p = multiprocessing.Process(target = info, args = ("apple",))p.start()p.join()  #父亲进程必须等待子进程干完活,执行后续代码print("继续执行父进程")

(2)join函数

join的作用:此子进程执行完后才会执行父进程

注意事项:默认主进程的结束不会影响子进程,join函数的作用是主进程要等子进程结束了才继续运行

import os
import multiprocessing
import timedef info(title):print(title)time.sleep(2)print(__name__)print("father ppid", os.getppid())print("self pid", os.getpid())print("-----------")if  __name__=="__main__":p1 = multiprocessing.Process(target=info, args=("A1",))p2 = multiprocessing.Process(target=info, args=("A2",))p3 = multiprocessing.Process(target=info, args=("A3",))p1.start() # 并发干活p2.start()p3.start()p1.join()p2.join()p3.join()# 等子进程执行完后再执行父进程print("all over")'''# 进程轮流干活p1.start()p1.join()p2.start()p2.join()p3.start()p3.join()'''

(3)锁

用multiprocessing.RLock

import os
import multiprocessing
import time# 多进程,并发,乱序并发执行,容易出错
# 多进程加锁,挨个执行,解决出错,不过执行顺序仍然是乱序def showdata(lock, i):   #将锁作为函数参数time.sleep(5)with lock:print(i)if __name__ == "__main__":lock = multiprocessing.RLock() #创建锁for num in range(10):multiprocessing.Process(target=showdata, args=(lock, num)).start()  #匿名对象

(4)管道

这里用用multiprocessing.Pipe,创建管道可用于进程间通信。

创建的管道有两个口,管道的一个口只能在一个进程中使用,不能用同一个口在一个进程发消息,在另一个进程接受消息。

注意管道的口两个都要被使用才行。

import multiprocessing
import time
import osdef showdata(conn):  #conn类型conn.send("发送的数据a")  #发送的数据print(os.getpid(), conn.recv(), time.time())  #收到的数据conn.close()  #关闭if __name__ == "__main__":conn_a, conn_b = multiprocessing.Pipe()  #创建一个管道,两个口# print(id(conn_a),id(conn_b))# print(type(conn_a), type(conn_b))p = multiprocessing.Process(target=showdata, args=(conn_a,))p.start()conn_b.send("要发送的数据b")print(os.getpid(), conn_b.recv(), time.time())conn_b.close()

(5)队列

这里用multiprocessing.Queue,进程进程间通信。

使用队列传输数据时,父进程和子进程都可以put数据,但当其中一个进程put数据成功时,另一个进程put数据就会失败

因此单项通信:要么①父进程插入,子进程读取;要么②子进程写入,父进程读取

import multiprocessingdef func(queue):print(id(queue))queue.put("子进程加入数据")#print(queue.get())if __name__ == "__main__":myqueue = multiprocessing.Queue()p = multiprocessing.Process(target=func, args=(myqueue,))p.start()#myqueue.put("主进程加入数据")print(myqueue.get())

(6)多进程中普通全局变量无法共享

在多进程中,普通的全局变量不会被共享

import multiprocessing
import time
import osdatalist = [] #全局变量def adddata(datalist):datalist.append(1)datalist.append(2)datalist.append(3)print(os.getpid(), os.getppid(), datalist, time.time())if __name__ == "__main__":p = multiprocessing.Process(target=adddata, args=(datalist,))p.start()time.sleep(2)datalist.append("a")datalist.append("b")datalist.append("c")print(os.getpid(), os.getppid(), datalist, time.time())

(7)进程间数据共享

1.使用multiprocessing.Queue() 

import multiprocessing
import os
import timedef adddata(queue, i):#time.sleep(2)  #说明父进程会等待子进程执行完毕后再执行queue.put(i)print("put", i, os.getppid(), os.getpid(), time.time())if __name__ == "__main__":queue = multiprocessing.Queue()  # 队列可以实现共享-单向mylist = []for i in range(10): #创建10个进程p = multiprocessing.Process(target=adddata, args=(queue, i))p.start()#print("queue.get()", queue.get())  # 加入此语句会程序会卡在put 0#time.sleep(2)mylist.append(queue.get())print(mylist)

2.使用multiprocessing.Value

import multiprocessingdef func(num):num.value = 10.78if  __name__ == "__main__":num = multiprocessing.Value("d", 10.0) # d表示数类型,可以多个进程之间共享print(num.value)p = multiprocessing.Process(target=func, args=(num,))p.start()p.join() #不要此语句会有变化print(num.value)

3.使用multiprocessing.Array

个人感觉使用array不太方便

import multiprocessingdef func(array):array[2] = 9999#array.append(888)  #没有append方法if  __name__ == "__main__":myarray = multiprocessing.Array("i", [1, 2, 3, 4, 5])print(myarray[:])p = multiprocessing.Process(target=func, args=(myarray,))p.start()p.join()print(myarray[:])

4.使用multiprocessing.Manager().list或dict

import multiprocessing
import timedef func(mydict, mylist):mydict["id"] = 54321mydict["name"] = "python"mylist.append("李四")if __name__ == "__main__":mydict = multiprocessing.Manager().dict()mylist = multiprocessing.Manager().list()mydict["id"] = 12345mylist.append("张三")print(mydict, mylist)p = multiprocessing.Process(target=func, args=(mydict, mylist))p.start()p.join()  #注意此语句的重要性# 没有此语句,父进程会在子进程活未干完的情况下继续执行,可能导致冲突#time.sleep(5)print(mydict, mylist)

(8)守护进程

主进程创建守护进程

其一:守护进程会在主进程代码执行结束后就终止

其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

from multiprocessing import Process
import time
import randomclass Piao(Process):def __init__(self,name):self.name=namesuper().__init__()def run(self):print('%s is piaoing' %self.name)time.sleep(random.randrange(1,3))print('%s is piao end' %self.name)p=Piao('egon')
p.daemon=True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行
p.start()
print('主')

(9)进程信号量

同线程一样,信号量为1就相当于锁。

(10)进程间通信

参考:python进程间通信-CSDN博客


end

http://www.xdnf.cn/news/9426.html

相关文章:

  • 应用签名分发平台开发源码时数据储存是如何实现
  • vue3自定义指令来实现 v-focus 功能
  • LittleFS 小型文件系统(一)
  • HOW - 从0到1搭建自己的博客站点(三)
  • KV Cache:大模型推理加速的核心机制
  • shell脚本中的常用命令
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年5月27日第90弹
  • 【系分】论文模版
  • w笔记--Swagger
  • 开源即战力!从科研到商用:Hello Robot 移动操作机器人Stretch 3多模态传感融合(RGB-D/激光/力矩)控制方案
  • 仿真环境中机器人抓取与操作 - 上手指南
  • java常用工具类:实现文件下载
  • AD-PCB--电子设计学习思路 DAY 1
  • 从零到一:影刀RPA学习者的破局之路
  • 分布式系统中的消息幂等性与流量控制(一)
  • Vue组件技术全解析大纲
  • mediapipe标注视频姿态关键点(基础版加进阶版)
  • Navicat 17 SQL 预览时表名异常右键表名,点击设计表->SQL预览->另存为的SQL预览时,表名都是 Untitled。
  • 【Elasticsearch】scripted_upsert
  • 小白成长之路-计算机网络(四)
  • BUG调试案例十二:LM5117输出电压纹波偏大问题案例
  • 初识 ProtoBuf
  • 破解Docker镜像下载难题
  • 永磁同步电机控制算法--变结构PI调节器
  • 面向测试编程——SmartRefreshLayout的测试case
  • Ubuntu系统开放 45876/tcp 端口
  • Cookie、Session和Token鉴权
  • Python实用脚本:可视化分割txt标签数据
  • TWTSolutions水厂污水厂设计计算软件:化学强化絮凝单元
  • leetcode:1688. 比赛中的配对次数(python3解法,数学相关算法题)