1. 添加进程 Process
导入线程进程标准模块
import multiprocessing as mp
import threading as td
定义一个被线程和进程调用的函数
def job(a,d):
print('aaaaa')
创建线程和进程
t1 = td.Thread(target=job,args=(1,2))
p1 = mp.Process(target=job,args=(1,2))
注意:Thread和Process的首字母都要大写,被调用的函数没有括号,被调用的函数的参数放在args(…)中
分别启动线程和进程
t1.start()
p1.start()
分别连接线程和进程
t1.join()
p1.join()
完整的线程和进程创建使用对比代码
import multiprocessing as mp
import threading as td
def job(a,d):
print('aaaaa')
t1 = td.Thread(target=job,args=(1,2))
p1 = mp.Process(target=job,args=(1,2))
t1.start()
p1.start()
t1.join()
p1.join()
从上面的使用对比代码可以看出,线程和进程的使用方法相似
运用
在运用时需要添加上一个定义main函数的语句
if __name__=='__main__':
完整的应用代码:
import multiprocessing as mp
def job(a,d):
print('aaaaa')
if __name__=='__main__':
p1 = mp.Process(target=job,args=(1,2))
p1.start()
p1.join()
2. 存储进程输出 Queue
Queue的功能是将每个核或线程的运算结果放在队里中, 等到每个线程或核运行完毕后再从队列中取出结果, 继续加载运算。原因很简单, 多线程调用的函数不能有返回值, 所以使用Queue存储多个线程运算的结果
把结果放在 Queue 里
定义一个被多线程调用的函数,q 就像一个队列,用来保存每次函数运行的结果
#该函数没有返回值!!!
def job(q):
res=0
for i in range(1000):
res+=i+i**2+i**3
q.put(res) #queue
主函数
定义一个多线程队列,用来存储结果
if __name__=='__main__':
q = mp.Queue()
定义两个线程函数,用来处理同一个任务, args 的参数只要一个值的时候,参数后面需要加一个逗号,表示args是可迭代的,后面可能还有别的参数,不加逗号会出错
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
def job(q):
res=0
for i in range(1000):
res+=i+i**2+i**3
q.put(res) #queue
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)
运行的时候还是要在terminal中,最后运行结果为
499667166000
3. 效率对比 threading & multiprocessing
创建多进程 multiprocessing
和上节一样,首先import multiprocessing并定义要实现的job(),同时为了容易比较,我们将计算的次数增加到1000000
import multiprocessing as mp
def job(q):
res = 0
for i in range(1000000):
res += i + i**2 + i**3
q.put(res) # queue
因为多进程是多核运算,所以我们将上节的多进程代码命名为multicore()
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)
创建多线程 multithread
接下来创建多线程程序,创建多线程和多进程有很多相似的地方。首先import threading然后定义multithread()完成同样的任务
import threading as td
def multithread():
q = mp.Queue() # thread可放入process同样的queue中
t1 = td.Thread(target=job, args=(q,))
t2 = td.Thread(target=job, args=(q,))
t1.start()
t2.start()
t1.join()
t2.join()
res1 = q.get()
res2 = q.get()
print('multithread:', res1 + res2)
创建普通函数
最后我们定义最普通的函数。注意,在上面例子中我们建立了两个进程或线程,均对job()进行了两次运算,所以在normal()中我们也让它循环两次
def normal():
res = 0
for _ in range(2):
for i in range(1000000):
res += i + i**2 + i**3
print('normal:', res)
运行时间
最后,为了对比各函数运行时间,我们需要import time, 然后依次运行定义好函数:
import time
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()
print('multicore time:', time.time() - st2)
普通/多线程/多进程的运行时间分别是1.13,1.3和0.64秒。 我们发现多核/多进程最快,说明在同时间运行了多个任务。 而多线程的运行时间居然比什么都不做的程序还要慢一点,说明多线程还是有一定的短板的。 戳这里查看“多线程的短板是什么”。