Python多进程

Python多进程


什么是进程

  • 进程是操作系统对一个正在运行程序的抽象,是一个执行中的程序的实例,它提供一个独立的逻辑控制流与一个私有的地址空间
  • 独立的逻辑控制流:它提供一个假象,好像我们的程序独占的使用处理器
  • 私有的地址空间:它提供一个假象,好像我们程序独占的使用存储器系统
  • 进程是孤立的,互相不共享状态,但它们可以彼此通信。
  • 由于python的全局解释器锁(Global Interpreter Lock,GIL)限制,我们难以将线程有效地限制到一个核中。所以如果要使用计算机的所有核,多进程的程序是必需的。

multiprocessing模块

  1. multiprocessing 模块会在windows上模拟出fork效果,可以实现跨平台,所有在python下,大多数的多进程都是使用multiprocessing.

创建进程:

  1. multiprocessing.Process([group[, target[, name[, args[, kargs]]]]])

    参数:
    group: None,它的存在仅仅是为了与threading.Thread兼容
    target: 一般是函数(当进程启动时执行的可调用对象)
    name: 进程名(为进程制定描述性名称的字符串)
    args: 函数的参数(传递给target的位置参数的元组)
    kargs: keywords参数(传递给target的关键字参数的字典)    
    
  2. 函数

    1. run() 默认的run()函数调用target的函数,你也可以在子类中覆盖该函数
    2. start() 启动该进程
    3. join([timeout]) 等待进程终止。timeout是可选的超时期限。进程可以被join无数次,但不能join自己(阻塞当前进程,直到调用join方法的那个进程执行完,再继续执行当前进程(比如在主进程中调用两个子进程,两个子进程都调用join方法,那么在会阻塞主进程,直到两个子进程执行完毕,主进程才继续执行.))
    4. is_alive() 如果进程仍然运行,返回True
    5. terminate() 强制终止进程。注意,该函数不会做任何清理动作,并可能会造成僵死进程,慎用!
  3. 属性:

    1. name 进程名
    2. daemon 一个Boolean标志,指示进程是否是后台进程
    3. pid 进程ID
    4. exitcode 进程的整数退出代码。如果进程仍然在运行,它的值为None。如果值为负数,-N表示进程由信号N所终止
    5. authkey 进程的身份验证键
  4. 代码

    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 %s.' % os.getpid()
        p = Process(target=run_proc, args=('test',))
        print 'Process will start.'
        p.start()
        p.join()
        print 'Process end.
    

    运行结果:

    Parent process 5372.
    Process will start.
    Run child process test (5756)...
    Process end.
    

进程之间通信

  • Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。

Queue方式:

    #-*-coding:utf-8-*-
    from multiprocessing import Process, Queue
    import os, time, random

    # 写数据进程执行的代码:
    def write(q):
        for value in ['A', 'B', 'C']:
            print 'Put %s to queue...' % value
            q.put(value)
            time.sleep(random.random())

    # 读数据进程执行的代码:
    def read(q):
        while True:
            value = q.get(True)
            print 'Get %s from queue.' % value

    if __name__=='__main__':
        # 父进程创建Queue,并传给各个子进程:
        q = Queue()
        pw = Process(target=write, args=(q,))
        pr = Process(target=read, args=(q,))
        # 启动子进程pw,写入:
        pw.start()
        # 启动子进程pr,读取:
        pr.start()
        # 等待pw结束:
        pw.join()
        # pr进程里是死循环,无法等待其结束,只能强行终止:
        pr.terminate()      

Pipe方式 :
from multiprocessing import Process, Pipe

def f(conn):
    conn.send([42, None, 'hello'])
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print parent_conn.recv()   # prints "[42, None, 'hello']"

通过pool来建立进程池

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)              # start 4 worker processes
    result = pool.apply_async(f, [10])    # evaluate "f(10)" asynchronously
    print result.get(timeout=1)           # prints "100" unless your computer is *very* slow
    print pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"

参考资料:

  1. https://shenwang.blog.ustc.edu.cn/python-%E5%A4%9A%E8%BF%9B%E7%A8%8B/
  2. http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868323401155ceb3db1e2044f80b974b469eb06cb43000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值