python总结(十六):多进程

一、多进程实现

1.用进程池方法:

    例子:假设有两个任务:run_proc()、long_time_task()需要并行执行。

# encoding = utf8
from multiprocessing import Process,Queue,Pool
import os, time, random
def run_proc():
    """第一个进程"""
    print("第一个进程开始")
    time.sleep(10)
    print('第一个进程结束')
def long_time_task():
    """第二个进程"""
    print("第二个进程开始")
    time.sleep(10)
    print('第二个进程结束Run task (%s)...' % (os.getpid()))
def mul_run():
    """多进程方式运行任务"""
    start = time.time()
    p = Pool(2)
    for L in [run_proc, long_time_task]:
        p.apply_async(L, args=())
    p.close()
    """对Pool对象调用join()方法会等待所有子进程执行完毕,
       调用join()之前必须先调用close(),
       调用close()之后就不能继续添加新的Process了"""
    p.join()
    end = time.time()
    print("多进程执行时间: ", end -start)
def run():
    """不用多进程执行时间"""
    start = time.time()
    run_proc()
    long_time_task()
    end = time.time()
    print("单进程执行时间: ", end -start)
if __name__=='__main__':
    mul_run()
    run()

    执行结果:  

E:\soft\python3\python.exe C:/Users/Lenovo/PycharmProjects/matplot_graph/Dict.py
第一个进程开始
第二个进程开始
第一个进程结束
第二个进程结束Run task (18544)...
多进程执行时间:  10.208519697189331
第一个进程开始
第一个进程结束
第二个进程开始
第二个进程结束Run task (4124)...
单进程执行时间:  20.00142812728882

Process finished with exit code 0

2、普通方式

# encoding = utf8
from multiprocessing import Process,Queue,Pool
import os, time, random
def run_proc():
    """第一个进程"""
    print("第一个进程开始")
    time.sleep(10)
    print('第一个进程结束')
def long_time_task():
    """第二个进程"""
    print("第二个进程开始")
    time.sleep(10)
    print('第二个进程结束Run task (%s)...' % (os.getpid()))
def mul_run():
    """多进程方式运行任务"""
    proList = []
    start = time.time()
    for L in [run_proc, long_time_task]:
        p = Process(target=L, args=())
        proList.append(p)
    """保证进程同时进行"""
    for t in proList:
        t.start()
    """保证进程都结束"""
    for t in proList:
        t.join()
    end = time.time()
    print("多进程执行时间: ", end -start)
def run():
    start = time.time()
    run_proc()
    long_time_task()
    end = time.time()
    print("单进程执行时间: ", end -start)
if __name__=='__main__':
    mul_run()
    run()

    执行结果: 

E:\soft\python3\python.exe C:/Users/Lenovo/PycharmProjects/matplot_graph/Dict.py
第一个进程开始
第二个进程开始
第一个进程结束
第二个进程结束Run task (11652)...
多进程执行时间:  10.093430280685425
第一个进程开始
第一个进程结束
第二个进程开始
第二个进程结束Run task (6444)...
单进程执行时间:  20.00089693069458
Process finished with exit code 0

二、让python执行命令行

1、子进程方式

  subprocess模块可以让我们非常方便地启动一个子进程,然后控制其输入和输出。下面的例子演示了如何在Python代码中运行命令“pip”,这和命令行直接运行的效果是一样的:

import subprocess
p = subprocess.Popen(['pip'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = p.communicate(b'set q=mx\npython.org\nexit\n')
print(output.decode('gb2312'))
print('Exit code:', p.returncode)

        如果子进程还需要输入,则可以通过communicate()方法输入。

2、如果不想传参数,且希望得到返回值。用:os.popen()

import os
strList = os.popen("pip").readlines()
print strList

 3.如果仅仅是执行,不传参,也不想得到返回值,用os.system()

os.system("cd /home/map/opt/lstm-name-comp;rm " + fileName)

三、进程间通信

1、Queue方式:

  • Put方法:以插入数据到队列中,他还有两个可选参数:blocked和timeout。详情自行百度

  • Get方法:从队列读取并且删除一个元素。同样,他还有两个可选参数:blocked和timeout。详情自行百度

from multiprocessing import Process, Queue
import os, time, random
def proc_write(q,urls):
    print('Process is write %s' % os.getpid())
    for url in urls:
        q.put(url)
        print('put %s to queue... ' %url)
        time.sleep(1)
def proc_read(q):
    print('Process is reading  %s' % os.getpid())
    while True:
        url = q.get(True)
        print('Get %s from queue' %url)
def multi_pro():
    w_list = []
    r_list = []
    q = Queue()
    proc_write1 = Process(target=proc_write, args=(q, ['url_1', 'url_2', 'url_3']))
    w_list.append(proc_write1)
    proc_write2 = Process(target=proc_write, args=(q, ['url_4', 'url_5', 'url_6']))
    w_list.append(proc_write2)
    proc_reader = Process(target=proc_read, args=(q,))
    r_list.append(proc_reader)
    """启动读写进程"""
    for L in w_list + r_list:
        L.start()
    """等待写进程结束"""
    for L in w_list:
        L.join()
    """关闭读进程"""
    for L in r_list:
        L.terminate()
if __name__ == '__main__':
    multi_pro()

2、Pip管道方式:

(1)Pipe常用于两个进程,两个进程分别位于管道的两端

(2)Pipe方法返回(conn1,conn2)代表一个管道的两个端,Pipe方法有duplex参数,默认为True,即全双工模式,若为FALSE,conn1只负责接收信息,conn2负责发送,     

import multiprocessing
import os,time,random
def proc_send(pipe,urls):
    for url in urls:
        pipe.send(url)
        time.sleep(random.random())
def proc_recv(pipe):
    while True:
        print('Process rev:%s' %pipe.recv())
        time.sleep(random.random())
if __name__ == '__main__':
    pipe = multiprocessing.Pipe()
    p1 = multiprocessing.Process(target=proc_send,args=(pipe[0],['url_'+str(i) for i in range(10) ]))
    p2 = multiprocessing.Process(target=proc_recv,args=(pipe[1],))
    p1.start()
    p2.start()
    p1.join()
    p2.terminate()

 总结:队列方式优点是不限进程个数。缺点是不能全双工。

            管道方式可以全双工,但是只能两个两个进程通信。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值