Multiprocessing 实现多进程 Python

https://www.bilibili.com/video/BV1jW411Y7pv?spm_id_from=333.999.0.0&vd_source=d59d7bc22106d87da35c63b8af6491e8

文章目录

      • 什么是多进程?
      • 创建进程
      • queque 进程输出
      • 效率对比
      • 进程池 pool
      • 共享内存
      • lock 进程锁

在学习多进程之前,建议先看多线程教学

什么是多进程?

一般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想简化我们的工作
参数没有括号,因为我们是引用它
开头函数都是大写

queque 进程输出

将所有核的运算结果放到 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)

Multiprocessing 实现多进程 Python_第1张图片

进程池 pool

进程池把所有要运行到任务放到一个池子里,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 一次只能在一个进程中间计算一个东西

共享内存

Multiprocessing 实现多进程 Python_第2张图片
典型的四核的CPU,共享内存j就存在 L2当中。在多线程中,如果想共享变量,可以用全局变量。但在多进程中是不行的。我们只能使用共享内存,在多个核中进行数据交流。

import multiprocessing as mp

value = mp.Value('d', 1)	# 先要定义什么样的形式,什么样的type;然后再转入value的值。可以被每个核加载这个内存
array = mp.Array('i', [1, 3, 4])	# 只能是一个一维的列表

Multiprocessing 实现多进程 Python_第3张图片

lock 进程锁

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()

你可能感兴趣的