• Python入门学习笔记15(进程间数据共享)


    Python中的多线程实际上是伪多线程,无法利用多核CPU的并列运算优势,所以Python多线程适合用在IO密集型的程序中。

    而cpu运算密集型的程序的并发应该使用多进程。

    多进程之间的数据交互主要有Queue、Pipe和Manager,其中队列Queue和管道Pipe只能应用于相同主进程创建出来的进程间的数据交换,

    Manager则是可以应用于无关的两个进程间进行数据共享。

    Queue

    进程Queue与线程queue用法基本相同,但是Queue必须作为子进程的传入参数,否则因为不同进程内存独立的缘故是无法访问主进程中定义的Queue的。

    import time
    import multiprocessing
    from multiprocessing import Queue
    from multiprocessing import Lock
    
    pq = Queue()
    
    """
    注意多进程Queue必须作为参数传递给子进程,否则子进程是无法获取父进程中的变量的
    多进程Queue的实质是将Queue拷贝到各个进程之中,任何一个进程做出修改都会同步到其他进程的拷贝上
    """
    def pqGet(pq,lock):
        while True:
            item = pq.get()
            pq.put("a")
            #进程锁,防止屏幕输出混乱
            lock.acquire()
            print(item)
            lock.release()
            time.sleep(1)
    
    if __name__ == "__main__":
        #注意锁必须作为传入参数
        lock = Lock()
        for i in range(100):
            pq.put(i)
        for i in range(5):
            p = multiprocessing.Process(target = pqGet,args=(pq,lock,))
            p.start()
    

    Pipe

    管道Pipe一般用于两个进程间的数据交互。管道两端会自动进入阻塞状态。

    import multiprocessing
    from multiprocessing import Pipe
    
    def func(conn):
        print(conn.recv())
        conn.send([1,2,3,"asd"])
    
    if __name__ == "__main__":
        connFrom, connTo = Pipe()
        connFrom.send("hello")
        p = multiprocessing.Process(target=func,args=(connTo,))
        p.start()
        print(connFrom.recv())
    

    Manager

    Manager是一种高级的进程间数据共享的方法,支持Python所有的数据结构。

    与Queue和Pipe不同,Manager并不限定必须是同一父进程创建的进程间数据交换。

    Manager的本质是启动一个ManagerSever进程监听socket其它进程通过socker连接ManagerServer实现通信

    from multiprocessing import Process, Manager
    import multiprocessing,time
    
    def func(lst,index):
        print("[%d]first:" %index,lst)
        lst.append(100)
        print("[%d]second:" %index,lst)
        time.sleep(1)
    
    if __name__ == '__main__':
        mng = Manager()
        lst = mng.list([1,2,3,4,5])
        """
        对于manager的复杂数据类型,必须在创建的时候一次性赋值
        在创建之后的修改提交是不起作用的,所以下面第二第三条赋值语句是无效的
        """
        lst[1] = list([1, 2])
        lst[1].append(0.1)#err
        lst[1][1] = "hello"#err
    
    
        plst = []
        for i in range(2):
            p = multiprocessing.Process(target=func,args=(lst,i,))
            p.start()
            plst.append(p)
    
        for p in plst:
            p.join()
    
        print("main:",lst)
    

    Manager有一个必须注意的点,

    对于manager的复杂数据类型,必须在创建或修改的时候一次性赋值。

    在创建之后的修改提交是不起作用的,详见上面的示例程序

  • 相关阅读:
    javascript实现根据时间段显示问候语的方法
    视觉会议收藏一
    cv的期刊和会议
    CVPR2016 Paper list
    CVPR 2017 Paper list
    关注的牛人
    cvpr2016论文
    linux命令技巧:scp多文件远程拷贝
    linux命令技巧--df -lh:查看磁盘占用情况
    spark--01编译安装spark1.3.1
  • 原文地址:https://www.cnblogs.com/Hexdecimal/p/9418527.html
Copyright © 2020-2023  润新知