Python-多进程

一、多进程

from multiprocessing import Process
import os

def func1(num):
    print(num)

if __name__ == '__main__':
    print('主进程id为:', os.getpid()) #获取主进程id
    for i in range(10):
        p = Process(target=func1,args=(i,)) #创建子进程
        p.start() #调起子进程
        print('子进程名称为:', p.name)  #获取子进程名称
        print('子进程id为', p.pid)  #获取子进程id

 

二、同时运行多进程时,每个进程默认都拥有一份独立的数据;通过全局变量并不能实现进程间的数据通信

a = 1
def func2():
    global a
    a +=1
    print('子进程中的a:', a)  #子进程中的a: 2
if __name__ == '__main__':
    p = Process(target=func2)
    p.start()
    p.join()
    print('主进程中的a:', a) #主进程中的a: 1

 

三、进程间数据通信

1、借助Queue、pipe等进行通信

from multiprocessing import Process, Queue
import os, time, random


def write_queue(q):   #写数据到队列
    for value in range(10):
        print('Put %s to queue...'%value)
        q.put(value)
        time.sleep(2) #每隔2秒写入数据


def read_queue(q):    #从队列读取数据
    while True:
        value = q.get(True)
        print('Get %s from queue.' %value)
        time.sleep(3) #每隔3秒读取数据
        if q.empty(): #若队列为空,退出循环
            print('队列为空,请输入数据后再读')
            break

if __name__=='__main__':
    q = Queue()    #父进程创建Queue,传给子进程
    pw = Process(target=write_queue, args=(q,))
    pr = Process(target=read_queue, args=(q,))
    start = time.time()
    pw.start()     #启动子进程pw,写数据
    pr.start()     #启动子进程pr,读数据
    pw.join()
    end_pw = time.time()
    run_pw = end_pw - start #计算写数据的时间
    pr.join()               #terminate()可强行终止进程
    end_pr = time.time()
    run_pr = end_pr - start #计算读数据的时间
    print('写数据花费时间:', run_pw, '读数据花费时间', run_pr)

 

2、借助Manager实现进程间的数据通信;Manager支持的类型非常多,包括: Value,Array,list, dict,Queue, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event等

from multiprocessing import Process, Manager
import time


def func(p_dict, p_list): #入参:p_dict为字典,p_list为list
    for i in range(10):
        time.sleep(2)
        k = str(i) + '*' + str(i)
        p_dict[k] = i * i
    for i in range(10):
        time.sleep(1)
        p_list.append(i)

if __name__ == "__main__":
    manager = Manager()
    dt = manager.dict() #创建dict实例
    lt = manager.list() #创建list实例
    start = time.time()
    p = Process(target=func, args=(dt, lt))
    p.start()
    p.join()
    end = time.time()
    run_time = end - start
    print(dt, '\n', lt)
    print('运行时间为:',run_time) #运行时间大约为30s

 

四、进程池

1、通过apply_async()可批量创建子进程

2、从进程池获取进程时,先判断进程池是否已满;若进程池满了,则需要等待进程池重新有空余的进程(池中其他被调用的子进程结束),再继续

from multiprocessing import Pool
import time
def func2(num):
    time.sleep(2)
    print(num)
if __name__ == '__main__':
    start = time.time()
    pool = Pool(5)  #创建进程池,最多可同时运行5个子进程
    for i in range(5):
        pool.apply_async(func=func2,args=(i,)) #apply_async()调用子进程
    print('执行主程序')
    pool.close()
    pool.join()    #等待子进程结束再结束主进程
    end = time.time()
    run_time = end - start
    print(run_time)

run_time的时间取决于进程池的个数pool = Pool(N):

1)当N=2时,每次只能从进程池取2个子进程,5个子进程要分三次调用:run_time = 2 + 2 + 2

2)当N=3时,每次只能从进城池取3个子进程,5个子进程要分2次调用:run_time = 2 + 2

3)当N>=5时,可同时调用5个子进程:run_time = 2

 

posted on 2017-12-11 15:36  乔~惜  阅读(355)  评论(0编辑  收藏  举报