zoukankan      html  css  js  c++  java
  • Python之进程(multiprocessing)

    一、multiprocessing模块简介——进程基于“threading”的接口

    multiprocessing模块支持创建进程——使用threading模块相似的API。multiprocessing模块对本地和远程的并发都提供了支持,使用子进程(subprocesses)来替代threads解决了GIL的限制。因此,multiprocessing模块允许程序充分利用给定设备的多核资源。在Unix和Windows系统都可以运行。

     multiprocessing模块同样引入了threading模块不支持的APIs。主要例子如:Pool对象提供了便捷并行执行(有多输入)的函数的执行,通过进程分发输入数据。下面就是一个简单的数据分发。

    from multiprocessing import Pool
    
    def f(x):
        return x*x
    
    if __name__ == '__main__':
        p = Pool(5)
        print(p.map(f, [1, 2, 3]))
    样例

    二、Process类

    在multiprocessing模块中,processes可以通过创建一个Process对象产生。然后调用其start()方法。Process和threading.Thread遵循threading.Thread的API。一个简单的多线程例子如下

    from multiprocessing import Process
    
    def f(name):
        print 'hello', name
    
    if __name__ == '__main__':
        p = Process(target=f, args=('bob',))
        p.start()
        p.join()
    样例

    显示相应的单个进程IDs,如下:

    from multiprocessing import Process
    import os
    import time
    
    
    def info(title):
        print(title)
        print('module name:', __name__)
        if hasattr(os, 'getppid'):
            print('parent process:',os.getppid())
        print('process id:', os.getpid())
    
    
    def f(name):
        time.sleep(2)
        info('function f')
        print('hello', name)
    
    if __name__ == '__main__':
    
        info('main line')
        p = Process(target=f,args=('bob',))
        p.start()
        p.join()
    样例

     三、Exchanging objects between processes进程间通讯

    1、Queue基本上是Queue.Queue的克隆版,但是本Queue是线程和进程都安全的

    from multiprocessing import Process, Queue
    import time
    
    
    def f(q):
        time.sleep(2)
        q.put([42, None, 'hello'])
        print('f')
    
    if __name__ == '__main__':
        q = Queue()
        p = Process(target=f, args=(q,))
        p.start()
        p.join()
        print('hello')
        print(q.get())
    样例

    2、Pipes是Pipe()函数返回一个连接对象对——由一个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())
        p.join()
    样例

    Pipe()返回两个连接(Connection)对象,代表管道的两端。每个连接对象都有send()和recv()方法(彼此之间)。

    注意:如果两个线程(或进程)同时尝试从pipe的同一端读写数据,管道里的数据可能损坏。如果同时在pipe()的两端读写是没有风险的。

    四、进程间的同步机制

    multiprocessing拥有threading模块相同的同步机制。例如,可以使用lock来保证一次只有一个进程打印到标准输出。

    from multiprocessing import Process,Lock
    import time
    
    
    def f(l, i):
        l.acquire()
        # time.sleep(2)
        print('hello world', i)
        l.release()
    
    if __name__ == '__main__':
        lock = Lock()
    
        for num in range(10):
            Process(target=f,args=(lock, num)).start()
    利用锁线程同步

    五、进程间共享状态

    如上所述,我们在做并发编程时,应当尽可能避免使用共享状态。有其是多进程。然而,你非得在多进程使用共享数据,multiprocessing提供了几种方来实现。

    1、Shared memory共享内存

    数据可以存储在共享内存里使用Value或Array。例如,如下代码:

  • 相关阅读:
    网络协议-应用层协议-HTTP协议简介
    网络协议-应用层协议-电子邮件协议
    网络协议-应用层协议-文件传输协议
    网络协议-应用层协议-远程登陆协议
    网络协议-应用层协议-概述
    网络协议-传输层协议-Socket编程
    网络协议-传输层协议-TCP协议
    网络协议-传输层协议-UDP协议
    北华大学网络赛题
    哈尔滨网络热身赛
  • 原文地址:https://www.cnblogs.com/skiler/p/7088397.html
Copyright © 2011-2022 走看看