https://www.bilibili.com/video/BV1jW411Y7pv?spm_id_from=333.999.0.0&vd_source=d59d7bc22106d87da35c63b8af6491e8
在学习多进程之前,建议先看多线程教学
一般Python程序只用到一个核一个线程
多线程实际上还是只能让计算机在同一时间处理一件事
多进程可以让计算机将任务平均分配给每一个核,每个核有单独的运算空间和运算能力
import multiprocessing as mp
import threading as td
def job(a, d):
print('aaaa')
if __name__ == '__main__': # 必须在这个框架下,不然它会报错
# t1 = td.Tread(target=job, args=(1, 2)) # 之前的 多线程创建
p1 = mp.Process(target=job, args=(1, 2) # 多进程创建 与多线程十分相似
# t1.start()
p1.start()
# t1.join()
p1.join()
multiprocessing 和 threading 十分相似,因为Python想简化我们的工作
参数没有括号,因为我们是引用它
开头函数都是大写
将所有核的运算结果放到 queue中,等到所有核运算完之后,再从队列中取出所有值,进行加载运算。
import multiprocessing as mp
import threading as td
def job(q):
res = 0
for i in range(1000):
res += i + i**2 + i**3
q.put(res)
if __name__ == '__main__':
q = mp.Queue()
p1 = mp.Process(target=job, args=(q,)) # 后面一定要跟',',证明它是一个可迭代的东西,表示之后还会输入额外的东西
p2 = mp.Process(target=job, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
res1 = q.get()
res2 = q.get()
print(res1 + res2)
import multiprocessing as mp
import threading as td
import time
def job(q):
res = 0
for i in range(1000000):
res += i + i**2 + i**3
q.put(res)
def multicore():
q = mp.Queue()
p1 = mp.Process(target=job, args=(q,)) # 后面一定要跟',',证明它是一个可迭代的东西,表示之后还会输入额外的东西
p2 = mp.Process(target=job, args=(q,))
p1.start()
p2.start()
p1.join()
p2.join()
res1 = q.get()
res2 = q.get()
print('multicore',res1 + res2)
def normal():
res = 0
for _ in range(2):
for i in range(1000000):
res += i + i**2 + i**3
print('normal:',res)
def multithread():
q = mp.Queue() # 我们用多进程的 q 来存放多线程,是没有问题的
p1 = td.Thread(target=job, args=(q,))
p2 = td.Thread(target=job, args=(q,))
t1.start()
t2.start()
t1.join()
t2.join()
res1 = q.get()
res2 = q.get()
print('multithread:', res1+res2)
if __name__ == '__main__':
st = time.time()
normal()
st1 = time.time()
print('normal time:', st1-st)
multithread()
st2 = time.time()
print('multithread time:', st2-st1)
multicore()
st3 = time.time()
print('multicore time:', st3-st2)
进程池把所有要运行到任务放到一个池子里,Python会自动给我们进行分配
import multiprocessing as mp
def job(x):
return x*x
def multicore():
pool = mp.Pool(processes=3) # 有了池子之后,我们就能将池子对应上所需要的的功能。往池子里丢数据,就能返回出这个结果。以前只能将值放进queue中,现在就有了return。processes 可指定所用核的数量,默认为所有核
res = pool.map(job, range(10)) # 往 pool 里面放入你的方程和你要运算的值,然后自动分配给每个进程,每个CPU核
print(res)
res = pool.apply_async(job, (2,)) # 传入一个值,后面一定要跟',',证明它可被迭代
print(rs.get())
multi_res = [pool.apply_async(job, (i,)) for i in range(10)] # 若要传入多个值,需要使用迭代器
print([res.get() for res in multi_res])
if __name__ == '__main__':
multicore()
map 可以放入很多迭代的参数,自动分配给进程。
apply_async 一次只能在一个进程中间计算一个东西
典型的四核的CPU,共享内存j就存在 L2当中。在多线程中,如果想共享变量,可以用全局变量。但在多进程中是不行的。我们只能使用共享内存,在多个核中进行数据交流。
import multiprocessing as mp
value = mp.Value('d', 1) # 先要定义什么样的形式,什么样的type;然后再转入value的值。可以被每个核加载这个内存
array = mp.Array('i', [1, 3, 4]) # 只能是一个一维的列表
import multiprocessing as mp
import time
def job(v, num, l):
l.acquire() // 锁住
for _ in range(10):
time.sleep(0.1)
v.value += num
print(v.value)
l.release() // 释放
def multicore():
l = mp.Lock() # 加入锁,防止进程抢资源
v = mp.Value('i', 0)
p1 = mp.Process(target=job, args=(v, 1, l))
p2 = mp.Process(target=job, args=(v, 3, l))
p1.start()
p2.start()
p1.join()
p2.join()