zoukankan      html  css  js  c++  java
  • python学习笔记 day37 Manager (IPC机制----进程之间互相通信)

    1. Manager可以提供进程之间共享的数据类型(list dict等)

    先撇开进程,单纯看一下使用Manager创建一个dict的例子(只不过使用Manager创建的dict,进程之间都可以使用)

    from multiprocessing import Manager
    from multiprocessing import Process
    if __name__=="__main__":
        m=Manager()  # 实例化一个Manage对象
        d=m.dict({"count":100})     # 使用Manager创建一个dict只不过这个字典可以在进程之间共享数据
        d["name"]="xuanxuan"
        print(d)

    运行结果:

    2. 使用Manager创建进程之间共享的dict:

    from multiprocessing import Manager
    from multiprocessing import Process
    import random
    import time
    
    def func(d):  # 子进程执行的函数
        print(d)
        d["count"]-=1  # 如果Manager创建的dict可以在进程之间共享数据,那么开多个进程执行func函数,字典的count每次都会减一操作
        time.sleep(random.random())
    if __name__=="__main__":
        m=Manager()   # 实例化一个Manager对象
        d=m.dict({"count":10})  # 使用Manager对象m创建了一个进程之间可以共享数据的字典d,并初始化未{"count":10}
        for i in range(10):
            p=Process(target=func,args=(d,))
            p.start()
            p.join()   # 判断进程是否结束,只有该子进程结束,才开下一个子进程(这样就变为同步的了) ,必须要加上这一句,否则打印出来的不对
            d["name"] = "xuanxuan"  # 第一个进程执行完之后,给d增加键值对,其他进程会接受到

    运行结果:

     (注意这里打印的是开启进程打印本次减之前的count值,第一个进程打印的10 接下来减一,,,最后开10个进程,最终得到的d count应该减10次变为0的,这里count=1是第十次减之前的,打印完之后才进行减一操作)

     3. 使用Manager创建的进程之间共享的dict,异步实现进程之间通信:

    from multiprocessing import Manager
    from multiprocessing import Process
    import time
    import random
    
    def func(d):
        # print(d)
        d["count"]-=1
        time.sleep(random.random())
    
    if __name__=="__main__":
        m=Manager()
        d=m.dict({"count":10})
        P=[]  # 存放开启的进程
        for i in range(10):
            p=Process(target=func,args=(d,))
            p.start()
            # p.join()   # 判断该子进程是否结束,结束了才会继续开下一个进程(所以这样就会变成同步的)
            P.append(p)  # 把开启的进程放在列表中
        [p.join() for p in P]  # 把刚才开的10个进程放在列表,该语句执行代表开的10个进程全部结束
        print(d)  # 实现异步,就不再是开一个结束一个,再开下一个进程这样的同步过程,所有进程全都打开,然后一起判断结束,就是西安了异步

    运行结果:

    正常情况下开启10个子进程,减10次得到的应该是0,但是这里异步实现之后,得到的count变为1 说明好像少减了一次,其实是两个进程在同一时间操作func中的字典d数据,两者同时进行减一操作,减完了放回去,但是效果其实就是减了一次(比如两个进程同时拿到的count为7 都进行减一操作,都把count变为6,都放回去,所以表面上看 ,这两个进程相当于只进行了一次减一操作)

    这就造成了数据的不安全,所以使用Manager创建的进程之间共享数据的dict是不安全的,有可能多个进程同时操作数据,所以应该加锁:

    from multiprocessing import Process
    from multiprocessing import Manager
    from multiprocessing import Lock
    import random
    import time
    
    def func(d,lock):  # 子进程执行该函数,但是每一个子进程拿到之后会先拿一把钥匙,占用资源,其他进程只能等待该进程执行完毕,释放钥匙,这就保证了开多个进程数据安全
        lock.acquire()  # 进程加锁,进程执行到func先获得锁,使得同一时间只有一个进程可以操作func,等进程执行完d["count"]-=1 再释放锁
        d["count"]-=1
        time.sleep(random.random())
        lock.release()
    
    if __name__=="__main__":
        m=Manager()
        d=m.dict({"count":10})
        lock=Lock()
        P=[]  # 存放开的进程,等到所有进程都结束,而不是开一个进程,判断结束,再开下一个进程造成的同步,一下开很多进程,最后一起判断结束这样可以实现异步
        for i in range(10):
            p=Process(target=func,args=(d,lock))
            p.start()
            P.append(p)
        [p.join() for p in P]  # 开的多个进程,一起判断进程是否结束(这里一定要判断进程是否结束,否则会报错,不知道为什么Eva-)
        print(d)  # 加了锁之后,这样数据就安全了,同一时间只有一个进程可以操作func,所以不会出现两个进程同时操作dict的count的情况,加锁之后得到的d["count"]一定是0

     运行结果:

    talk is cheap,show me the code
  • 相关阅读:
    win8.1下安装双系统ubuntu14.04.3
    如何使用cmd
    My Test about Mat
    访问Mat矩阵中的元素并为其赋值
    Mat代码操作
    waitKey()
    ASCII码对照表
    vector 中的clear()
    vector 介绍
    Mat的详解
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9783648.html
Copyright © 2011-2022 走看看