什么是多进程?
我们在多线程 (Threading) 里提到过, 它是有劣势的, GIL 让它没能更有效率的处理一些分摊的任务. 而现在的电脑大部分配备了多核处理器, 多进程 Multiprocessing 能让电脑更有效率的分配任务给每一个处理器, 这种做法解决了多线程的弊端. 也能很好的提升效率.
也就是 电脑有多核的处理器, 多核运算
1.2 创建进程 Process
# 创建进程"""添加进程模块 multiprocessing添加进程的 命令 Processtarget=job 表示 要执行的进程 函数名args=() 表示传入的 参数name="" 表示进程的名字"""import multiprocessing as mp # 多进程模块import threading as td #多线程模块def job(a,b):print("aaaa",a,b)# 多线程 与多进程的命令对比if __name__ == "__main__":# t1= td.Thread(target=job, args=(1,2)) # 添加(创建)线程p1 = mp.Process(target=job, args=(1, 2)) # 添加(创建)进程# t1.start()# t1.join()p1.start()p1.join()
1.3 存储进程输出 Queue
# 存储进程输出 Queueimport multiprocessing as mp # 多进程模块def job(q):res = 0for i in range(1000):res += i + i**2 + i **3q.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)------------------------499667166000
1.4 效率对比 threading & multiprocessing
# 存储进程输出 Queueimport multiprocessing as mp # 多进程模块import threading as tdimport timedef job(q):res = 0for i in range(100000):res += i + i**2 + i **3q.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 multithreading():q =mp.Queue()p1 = td.Thread(target=job, args=(q,)) # 加逗号表示 这个可以迭代的东西p2 = td.Thread(target=job, args=(q,)) # 添加(创建)进程p1.start()p2.start()p1.join()p2.join()res1= q.get()res2= q.get()print("multithreading",res1 + res2)def normal():res = 0for _ in range(2):for i in range(100000):res += i + i**2 + i **3print("normal", res)# 多线程 与多进程的命令对比if __name__ == "__main__":st = time.time()normal()st1 = time.time()print("normal time:", st1 - st)multithreading()st2 = time.time()print("multithreading time:", st2 - st1)multicore()print("multicore time:", time.time() - st2)------------------------------normal 49999666671666600000normal time: 0.10569334030151367multithreading 49999666671666600000multithreading time: 0.13794255256652832multicore: 49999666671666600000multicore time: 0.26130223274230957
1.5 进程池 Pool
# 进程池""".Pool() 默认使用系统的全部核.Pool(processes=2) 指定使用核数.pool.map() 可使用无限的参数.pool.apply_async() 只能传入1个参数"""import multiprocessing as mpdef job(x):return x*xdef multicore():pool= mp.Pool() # 默认启动全部# pool = mp.Pool(processes=2) # processes 指定启动几个核进程# map 是可以放入很多个迭代的参数, 自动分配到进程,如果有2个进程,就自动分配res= pool.map(job,range(10))print(res)# apply_async 只能在一个进程里算一个东西,res = pool.apply_async(job,(2,)) # apply_async 只能传1个参数print(res.get())# 如果apply_async 想要达到map 的 效果, 就要把 apply_async 设置成迭代的效应,然后用迭代,把它的值传出来. 列表中的迭代 出来, 一个一个的拿出来multi_res = [pool.apply_async(job,(i,)) for i in range(10)]print([res.get() for res in multi_res])if __name__ == "__main__":multicore()----------------------[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]4[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
1.6 共享内存 shared memory
https://docs.python.org/3.5/library/array.html#module-array
import multiprocessing as mpmp.Value("d", 1)mp.array("i", [1,2,3]) # 只能定义一维的 数组,不能定义多维的
| 类型 code | C 类型 | Python 类型 | Minimum size in bytes | Notes |
|---|---|---|---|---|
| “b” | int | 1 | ||
| “B” | int | 1 | ||
| “u” | Unicode character | 2 | (1) | |
| “h” | int | 2 | ||
| “H” | int | 2 | ||
| “i” | int | 2 | ||
| “I” | int | 2 | ||
| “l” | int | 4 | ||
| “L” | int | 4 | ||
| “q” | int | 8 | (2) | |
| “Q” | int | 8 | (2) | |
| “f” | float | 4 | ||
| “d” | float | 8 |
1.7 进程锁
# 抢共享内存import multiprocessing as mpimport timedef job(v,num,L):L.acquire() # 加入了锁 锁住进程for _ in range(10):time.sleep(0.1)v.value += numprint(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()if __name__ == "__main__":multicore()--------------------不加进程锁___打印的很乱没有规律15913172125293337481216202428323640--------------------加入进程锁___打印的很规律1234567891013161922252831343740
