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

python多进程

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

相关文章:

  • 在 C++ 中,当回调函数是类的成员函数时,this指针的指向由调用该成员函数的对象决定
  • 4.8.5 利用Spark SQL统计网站每月访问量
  • MySQL事务机制介绍
  • Fastdata极数:中国公路跑步赛事白皮书2025
  • 演示:基于WPF开发的带有切换动画效果的登录和注册页面
  • 【Agent】MLGym: A New Framework and Benchmark for Advancing AI Research Agents
  • 初识 ProtoBuf
  • 攻防世界-你猜猜
  • JDK21深度解密 Day 7:FFM与VarHandle底层剖析
  • 九级融智台阶的要素协同跃迁框架
  • 应用层协议http(无代码版)
  • U 盘数据恢复全攻略
  • Linux下使用socat将TCP服务转为虚拟串口设备
  • LLM+RAG:文本分块处理策略
  • ProfiNet转MODBUSTCP网关模块的实时性保障Logix5000控制器与AltivarProcess变频器同步控制方案
  • 基于 OpenCV 和 DLib 实现面部特征调整(眼间距、鼻子、嘴巴)
  • TestStand API编程:SequenceFile 基本操作
  • 【C/C++】线程局部存储:原理与应用详解
  • React从基础入门到高级实战:React 核心技术 - React 与 TypeScript:构建类型安全的应用
  • 解析极限编程-拥抱变化(第2版)笔记
  • 国内高清视频素材网站/厦门网站seo哪家好
  • 个人网站要备案嘛/杭州网站seo
  • 重庆公司网站seo/大型网站建设
  • wordpress加载速度太慢/长沙seo网站排名优化公司
  • 网站空间服务器供应商/青岛seo博客
  • 做oa系统的网站/百度电脑端网页版入口