多进程
使用os模块中的fork构造进程; fork()方法只适用于Linux/Unix系统,是一个非常常见的系统调用的方法。 forn()方法调用一次,返回两次。该方法调用时,操作系统将当前进程即父进程进行了复制,即子进程,这两个进程完全相同。在父进程中,返回的是子进程的ID;在子进程中,返回的是永远是0。 测试程序fork_process.py 需要主要的是这个程序只能在LInux/Unix系统上运行,在Windows系统上会报错。但是在Windows上可以通过安装子系统运行。
import os
if __name__ == '__main__' :
print ( "当前进程的ID:%s" % os. getpid( ) )
pid = os. fork( )
if pid < 0 :
print ( "创建进程失败!!!" )
elif ( pid == 0 ) :
print ( "子进程的ID:%s,其父进程的ID:%s" % ( os. getpid( ) , os. getppid( ) ) )
else :
print ( "父进程的ID:%s,其子进程的ID:%s" % ( os. getpid( ) , pid) )
multiprocessing模块创建多进程 fork()方法虽然方便,但是最大的缺陷在于其只能运行在Linux/Unix系统上,在Windows系统上可以使用multiprocessing模块提供的Process类。 测试程序multiprocessing_process.py
通过Process类创建进程 Process类创建实例化对象,通过调用构造方法创建新进程。 start()方法启动新创建的进程; join()方法的作用是在多进程执行时,其他进程必须等到调用join()方法的进程结束之后(或者超出规定的时间)才能继续执行; 继承Process类创建进程 run()方法在使用继承类创建新进程的时候需要用到,包含新进程需要执行的代码;
import os
from multiprocessing import Process
def run_proc ( num) :
print ( "%s 号进程准备开始" % num)
print ( "%s 号进程正在运行...ID为:%s" % ( num, os. getpid( ) ) )
print ( "%s 号进程已结束" % num)
class MyProcess ( Process) :
def __init__ ( self, num) :
super ( ) . __init__( )
self. num = num
def run ( self) :
print ( "%s 号进程准备开始" % self. num)
print ( "%s 号进程正在运行...ID为:%s" % ( self. num, os. getpid( ) ) )
print ( "%s 号进程已结束" % self. num)
if __name__ == '__main__' :
print ( "进程正在运行...ID为:%s" % os. getpid( ) )
for i in range ( 3 ) :
p = Process( target= run_proc, args= ( str ( i) , ) )
print ( "进程即将开始:" )
p. start( )
p. join( )
for i in range ( 3 ) :
my_process = MyProcess( i)
print ( "进程即将开始:" )
my_process. start( )
my_process. join( )
print ( "进程结束" )
进程池 在multiprocessing模块中,Pool类可以提供指定数量的进程供用户调用,默认大小是CPU的核数。在初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中,如果进程池还没满的话,那么就创建一个新的进程来执行该请求;如果池中的进程数已达到最大进程数,那么该请求就只能等待,直到进程池中有进程结束,然后创建新的进程来处理该请求。 测试程序multiprocessing_pool.py
from multiprocessing import Pool
import os, time, random
def run_mytask ( num) :
print ( "进程%s正在运行...ID%s" % ( num, os. getpid( ) ) )
time. sleep( random. random( ) * 2 )
print ( "进程%s结束" % num)
if __name__ == '__main__' :
print ( "当前进程 %s " % os. getpid( ) )
pool = Pool( processes= 3 )
for i in range ( 4 ) :
pool. apply_async( run_mytask, args= ( i, ) )
print ( "等待所有进程结束" )
pool. close( )
pool. join( )
print ( "所有进程结束" )
进程间通信 对于多进程而言,进程间的通信是十分关键的操作。
Queue通信方式 Queue通信方式用于在多个进程之间实现通信。 测试程序multiprocessing_queue.py
from multiprocessing import Process, Queue
import os, time, random
def run_writer ( queue, nums) :
print ( "写进程正在运行 ID:%s" % os. getpid( ) )
for num in nums:
queue. put( num)
print ( "将 %s 放入 queue中..." % num)
time. sleep( random. random( ) )
print ( "写进程结束 ID:%s" % os. getpid( ) )
def run_reader ( queue) :
print ( "读进程正在运行 ID:%s" % os. getpid( ) )
while not queue. empty( ) :
num = queue. get( True )
print ( "从中取出数据 %s " % num)
time. sleep( random. random( ) )
print ( "读进程结束 ID:%s" % os. getpid( ) )
if __name__ == "__main__" :
print ( "当前进程ID:%s" % os. getpid( ) )
queue = Queue( )
proc_writer1 = Process( target= run_writer, args= ( queue, [ 1 , 2 , 3 ] ) )
proc_writer2 = Process( target= run_writer, args= ( queue, [ 4 , 5 , 6 ] ) )
proc_reader = Process( target= run_reader, args= ( queue, ) )
proc_writer1. start( )
proc_writer2. start( )
proc_reader. start( )
proc_writer1. join( )
proc_writer2. join( )
proc_reader. join( )
print ( "主进程结束 ID:%s" % os. getpid( ) )
Pipe通信方式 Pipe常用来在两个进程之间进行通信,其中两个进程分别位于管道的两端。 测试程序multiprocessing_pipe.py
from multiprocessing import Process, Pipe
import time, os, random
def run_send ( pipe, nums) :
print ( "发送进程正在运行 ID: %s" % os. getpid( ) )
for num in nums:
pipe. send( num)
time. sleep( random. random( ) )
def run_recv ( pipe) :
print ( "接收进程正在运行 ID: %s" % os. getpid( ) )
while True :
print ( "接收到:%s" % pipe. recv( ) )
time. sleep( random. random( ) )
if __name__ == '__main__' :
print ( "主进程ID %s正在运行..." % os. getpid( ) )
pipe = Pipe( )
proc_send = Process( target= run_send, args= ( pipe[ 0 ] , [ i for i in range ( 4 ) ] ) )
proc_recv = Process( target= run_recv, args= ( pipe[ 1 ] , ) )
proc_send. start( )
proc_recv. start( )
proc_send. join( )
proc_recv. join( )
print ( "主进程ID %s结束..." % os. getpid( ) )