进程
首先复习一下进程的概念,多线程可以让电脑同时处理多个事务,比如一边听音乐一边写论文,看上去是并行的。对于单核处理器,这里的并行其实只是人的感觉,事实上是通过操作系统的进程调度把多个进程以很短时间的轮转运行,如音乐0.001s,论文0.001s因为处理器的速度很快,所以看上去像是并行。对于多核处理器,可以同时处理多个进程,但是因为进程比我们现象的多,所以一般也是以上述办法调度的。
而对于一个进程,包含了多个线程,线程一般共享一个进程内的数据。一个进程内的线程也是可以并行的,就好像一边用word写论文,word同时在审计你的错别字。
这里可以看出,start后join才会真正开始进程
multiprocessing
模块是跨平台版本的多进程模块。
multiprocessing
模块提供了一个Process
类来代表一个进程对象,下面的例子演示了启动一个子进程并等待其结束:
from multiprocessing import Process import os # 子进程要执行的代码 def run_proc(name): print('Run child process %s (%s)...' % (name, os.getpid())) if __name__=='__main__': print('Parent process id %s.' % os.getpid()) pChild = Process(target=run_proc, args=('Kid',)) print('Child process will start.') pChild.start() print("After start") pChild.join() print('Child process end.')
之后介绍pool,用进程池的方式批量创建子进程:
from multiprocessing import Pool import os, time, random def long_time_task(name): print('Run task %s (%s)...' % (name, os.getpid())) start = time.time() time.sleep(random.random() * 3) end = time.time() print('Task %s runs %0.2f seconds.' % (name, (end - start))) if __name__=='__main__': print('Parent process %s.' % os.getpid()) p = Pool(4) for i in range(5): #进入循环但是不执行多进程 print("in for") p.apply_async(long_time_task, args=(i,)) print('Waiting for all subprocesses done...') p.close() print("start_here?") #开始执行多进程 p.join() print('All subprocesses done.')
对Pool
对象调用join()
方法会等待所有子进程执行完毕,调用join()
之前必须先调用close()
,调用close()
之后就不能继续添加新的Process
了。
请注意输出的结果,task 0
,1
,2
,3
是立刻执行的,而task 4
要等待前面某个task完成后才执行,这是因为Pool
的默认大小在我的电脑上是4,因此,最多同时执行4个进程。这是Pool
有意设计的限制,并不是操作系统的限制。如果改成:
p = Pool(5)
就可以同时跑5个进程。
由于Pool
的默认大小是CPU的核数,如果你不幸拥有8核CPU,你要提交至少9个子进程才能看到下面的等待效果。
参考网站:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431927781401bb47ccf187b24c3b955157bb12c5882d000#0