python之多进程multiproce

发布时间:2019-09-16 07:13:59编辑:auto阅读(1649)


    一:multiprocess基本使用

        multiprocessing是要比fork更高级的库了,使用multiprocessing可以更加轻松的实现多进程程序。multiprocessing也提供了很多进程同步和进程通信的方法。

        

    #!/usr/bin/env python
    import multiprocessing
    import time
    def clock(interval):
            while True:
                    print "The time is {0}".format(time.ctime())
                    time.sleep(interval)
    if __name__ == "__main__":
            for i in range(3):
                    p = multiprocessing.Process(target=clock,args=(1,))
                    p.start()
                    p.join()

        join()代表启动多进程,但是阻塞并发运行,一个进程执行结束后再执行第二个进程。可以给其设置一个timeout值比如join(5)代表5秒后无论当前进程是否结果都继续并发执行第二个进程。


    二:进程同步

        对于一些互斥的资源来说,进程间需要进程互斥来访问。否则导致资源访问受阻,或者最后的结果混乱等情况。对于标准输出这个资源来说,如果多个资源同属输出信息,可能会导致输出的信息混乱。所以需要使用锁来避免资源互斥访问。

    from multiprocessing import Process,Lock
    def f(l,i):
           l.acquire()
           print "hello world",i
           l.release()
    
    if __name__ == "__main__":
            lock = Lock()
            for num in range(10):
                    Process(target=f,args=(lock,num)).start()


    三:进程通信

        两个进程直接运行的时候如果希望可以让进程间通信的话是需要借助multiprocessing中的一些机制来实现。

    一:方式一Queue

    from multiprocessing import Process,Queue
    
    def f(q):
            q.put([1,2,3,4])
    
    if __name__ == '__main__':
            q = Queue()
            p = Process(target=f,args=(q,))
            p.start()
            print q.get()
            p.join()

    二:方式二Pipe

    #/usr/bin/env python
    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())


    四:进程共享变量

        几个进程之间的都拥有自己独立的命名空间和地址空间,无法通过一些全局变量来实现,multiprocessing提供了一些特殊的函数来实现共享变量。

    1.Value,Array的方式

    from multiprocessing import Process,Value,Array
    def f(n,a):
            n.value = 3.1415926
            for i in range(len(a)):
                    a[i] = -a[i]
    if __name__ == "__main__":
            num = Value('d',0.0)
            arr = Array('i',range(10))
            p = Process(target=f,args=(num,arr))
            p.start()
            p.join()
            print num.value
            print arr[:]

        Value()和Array()都有两个参数第一个参数代表存放的值的类型,第二个参数代表其值。


    2.Manager的方式

        这个方式支持的类型更多,灵活性更大,但是速度要慢于Value,Array。

    from multiprocessing import Process,Manager
    def f(d,l):
            d[1] = '1'
            d['2'] = 2
            d[0.25] = None
            l.reverse()
    if __name__ == "__main__":
            manager = Manager()
            d = manager.dict()
            l = manager.list(range(10))
            p = Process(target=f,args=(d,l))
            p.start()
            p.join()
            print d
            print l

    五:Pool的使用

       

    from multiprocessing import Pool
    def f(x):
        return x*x
    if __name__ == '__main__':
        pool = Pool(processes=5)
        result = pool.apply_async(f, [10])
        print result.get(timeout=1)
        print pool.map(f, range(10))

    pool常用的函数有:

    apply 开启多个进程并发执行

    apply_async 同上,但是这个是异步的,非阻塞的。

    map 类似于内建函数map,后面提供的参数列表会一个一个应用于函数,。这里会开发多个进程并发一起执行。

    map_async 和map相同,只不过这是一个异步的,不会阻塞等待结果。该函数会返回一个结果对象。


关键字