文章来源:https://www.liaoxuefeng.com/discuss/969955749132672/1294194291245090
先说两句:什么是进程?有什么用?——ok,那我问你,你能一手画圆一手画方吗?——我猜不能。但计算机就不一样了,一边绘制正方体一边绘制球体都是小case(屏幕上自动绘制图形),这是因为计算机启动了另一个"大脑"来处理另一个任务,即两个“大脑”分别同时画两个图形 效率X2!我们之前的写程序都是计算机一个“大脑”在工作!ok,那怎么启动计算机其他的大脑呢?——启动另一个进程就可以了!
1、创建进程:
import multiprocessing
import time
def action(a, b): # 待会两个进程要执行的任务↓
for i in range(30): # 循环30次
print(a, ' ', b)
time.sleep(0.1) # 等待0.1s
if __name__ == '__main__': # 这行代码很重要,新建进程的时候都加上它!!原因不用管(我也不知道233)
jc1 = multiprocessing.Process(target=action, args=('进程一', 0)) # 准备建立一个进程:multiprocessing.Process()
jc2 = multiprocessing.Process(target=action, args=('进程二', 1)) # 再准备建立一个新进程,这是基本格式记住←
# 必要参数target:指定进程要执行的任务(这里是执行函数 action),必要参数args:直译成中文就是'参数',顾名思义就是前面target的参数,即action的参数,注意args是个元组,所以args后的参数写成tuple元组格式。直接写target('进程一',0)一定报错的
jc1.start() # 将蓄势待发的jc1进程正式启动!!
jc2.start() # 同上...
jc1.join() # 等待进程jc1将任务执行完...
jc2.join() # ...
print('jc1,jc2任务都已执行完毕')
jc1.close() # 彻底关闭进程jc1
jc2.close() # ...
输出结果是两个进程同时且连续打印0、1
2、Pool:(进程池)
import time
import os
def action1(a, b=50):
for i in range(b):
print(a, os.getpid(), ' ', i) # os.getpid(): pid简单来说就是每个进程的“身份证”
time.sleep(0.1)
if __name__ == '__main__': # 还要添加这行,否则可能出现异常
ci = Pool(3) # 创建一个进程池,容量为3个进程
ci.apply_async(action1, args=('进程一',)) # 启动第一个子进程...
ci.apply_async(action1, args=('进程二', 50)) # 和普通进程的启动方式有很大不同仔细看
ci.apply_async(action1, args=('进程三', 60)) # Pool的最基本格式记住←
# 注意:程序现在有4个进程在运行:上面的三个子进程 和一个最为核心的:主进程
ci.close() # 关闭进程池(但池子内已启动的子进程还会继续进行)
ci.join() # 等待进程池内的所有子进程完毕
print('比如说这最后的一行输出就是主进程执行任务打印出来的')
主进程(父进程)全程干了什么?创建进程池、启动子进程、关闭进程池、等待子进程完毕、打印最后一行
3、进程间的通信:
import multiprocessing
def foo(aa):
ss = aa.get() # 管子的另一端放在子进程这里,子进程接收到了数据
print('子进程已收到数据...')
print(ss) # 子进程打印出了数据内容...
if __name__ == '__main__': # 要加这行...
tx = multiprocessing.Queue() # 创建进程通信的Queue,你可以理解为我拿了个管子来...
jc = multiprocessing.Process(target=foo, args=(tx,)) # 创建子进程
jc.start() # 启子子进程
print('主进程准备发送数据...')
tx.put('有内鬼,终止交易!') # 将管子的一端放在主进程这里,主进程往管子里丢入数据↑
jc.join()
这种方法可以实现任意进程间的通信,这里写的是主、子进程间的通信
网友评论