书接上回:
1. 多进程
1.1 创建多进程
1)import multiprocessing模块
2)创建进程要执行的函数
3)调用multiprocessing.Process(target=函数名,args=(函数要传入的参数)) #只有一个参数时,后面要加一个逗号
4)p.start()启动进程
5)p.join()等待进程结束
例 1.1 :
import multiprocessing
import os
def fun1(a):
print('id = {0}'.format(os.getpid()))
print('a = {0}'.format(a))
if name == 'main':
p1 = multiprocessing.Process(target=fun1, args=(5,))
p2 = multiprocessing.Process(target=fun1, args=(6,))
p1.start()
p2.start()
p1.join()
p2.join()
1.2 queue
1)作用:将每个进程执行的结果存放到queue里,最后所有进程结束后从queue里拿出结果。
2)用法:
(1)通过multiprocessing.Queue()创建q
(2)将q作为第一个参数传入到multiprocessing.Process()里
(3)通过q.put(结果)将结果放入q里
(4)在进程结束后通过q.get()拿出结果 #先放入的结果会被先拿出来
例1 .2 :
import multiprocessing
import os
def fun1(q, a):
print('id = {0}'.format(os.getpid()))
print('a = {0}'.format(a))
q.put(a)
if name == 'main':
q = multiprocessing.Queue()
p1 = multiprocessing.Process(target=fun1, args=(q,5))
p2 = multiprocessing.Process(target=fun1, args=(q,6))
p1.start()
p2.start()
p1.join()
p2.join()
res1 = q.get()
res2 = q.get()
print('res1 : {0}'.format(res1))
print('res2 : {0}'.format(res2))
1.3 pool
1)作用:将任务放入进程池,不用自己去调度cpu
例1. 3 :
import multiprocessing
def func1(a):
return a*a
if name == 'main':
pool = multiprocessing.Pool() # 默认会调度所有的 CPU
# pool = multiprocessing.Pool(processes=4) # 还可以指定调度 4 个(或其他个数) CPU
# 方式一: map---- 可以一次传入多个参数
results = pool.map(func1, range(10)) # 第一个参数:要调度的函数;第二个参数:输入参数的取值范围 ----- 最终 pool 自己会去调度 cpu 来计算范围内所有输入值的计算结果
print(results)
# 方式二: apply_async---- 一次只能传入一个参数
result = pool.apply_async(func1, (2,))
print(result.get())
# 那么针对这种方式只能利用 for 的迭代来完成多个参数的计算
results = [pool.apply_async(func1, (i,)) for i in range(10)]
print([result.get() for result in results]) # 效果和方式一一样
1.4 shared memory
例1. 4 :
import multiprocessing
import time,os
def func1(a, shared_value):
for _ in range(6):
time.sleep(0.5)
shared_value.value += a
print('id : {0}, value : {1}\n'.format(os.getpid(), shared_value.value))
if name == 'main':
shared_value = multiprocessing.Value('i', 5) # 第一个参数:共享值的数据类型;第二个参数:共享值
p1 = multiprocessing.Process(target=func1, args=(1, shared_value))
p2 = multiprocessing.Process(target=func1, args=(3, shared_value))
p1.start()
p2.start()
p1.join()
p2.join()
# 在没有 lock 时,上述代码就会出现一个抢资源的混乱现象
1.5 lock
1)有了锁后,资源就不会出现混乱
例1 .5 :
import multiprocessing
import time,os
def func1(a, shared_value, lock):
lock.acquire() # lock
for _ in range(6):
time.sleep(0.5)
shared_value.value += a
print('id : {0}, value : {1}\n'.format(os.getpid(), shared_value.value))
lock.release() # 释放 lock
if name == 'main':
lock = multiprocessing.Lock()
shared_value = multiprocessing.Value('i', 5) # 第一个参数:共享值的数据类型;第二个参数:共享值
p1 = multiprocessing.Process(target=func1, args=(1, shared_value, lock))
p2 = multiprocessing.Process(target=func1, args=(3, shared_value, lock))
p1.start()
p2.start()
p1.join()
p2.join()
2. 多线程
例 2 :
import threading as td
def func1(a, b):
print('a + b = ', a+b)
if name == 'main':
t1 = td.Thread(target=func1, args=(1, 2)) # target: 执行的函数名称 agrs :执行的函数传参
t1.start() # start processing
t1.join() # wait process finished