zoukankan      html  css  js  c++  java
  • 共享数据, 信号量(了解),事件(了解)

    进程间通信应该尽量避免使用本节所讲的共享数据的方式
    进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的 虽然进程间数据独立,但可以通过Manager实现数据共享,事实上Manager的功能远不止于此 A manager object returned by Manager() controls a server process which holds Python objects
    and allows other processes to manipulate them using proxies. A manager returned by Manager() will support types list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array. For example,
    from multiprocessing import Manager,Process,Lock
    import os
    def work(d,lock):
        # with lock: #不加锁而操作共享的数据,肯定会出现数据错乱
            d['count']-=1
    
    if __name__ == '__main__':
        lock=Lock()
        with Manager() as m:
            dic=m.dict({'count':100})
            p_l=[]
            for i in range(100):
                p=Process(target=work,args=(dic,lock))
                p_l.append(p)
                p.start()
            for p in p_l:
                p.join()
            print(dic)
            #{'count': 94}
    进程之间操作共享的数据

    信号量

    互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去,如果指定信号量为3,那么来一个人获得一把锁,计数加1,当计数等于3时,后面的人均需要等待。一旦释放,就有人可以获得一把锁
    
        信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念
    
    from multiprocessing import Process,Semaphore
    import time,random
    
    def go_wc(sem,user):
        sem.acquire()
        print('%s 占到一个茅坑' %user)
        time.sleep(random.randint(0,3)) #模拟每个人拉屎速度不一样,0代表有的人蹲下就起来了
        sem.release()
    
    if __name__ == '__main__':
        sem=Semaphore(5)
        p_l=[]
        for i in range(13):
            p=Process(target=go_wc,args=(sem,'user%s' %i,))
            p.start()
            p_l.append(p)
    
        for i in p_l:
            i.join()
        print('============》')
    互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去,如果指定信号量为3,那么来一个人获得一把锁,计数加1,当计数等于3时,后面的人均需要等待。一旦释放,就有人可以获得一把锁
    
        信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念
    
    from multiprocessing import Process,Semaphore
    import time,random
    
    def go_wc(sem,user):
        sem.acquire()
        print('%s 占到一个茅坑' %user)
        time.sleep(random.randint(0,3)) #模拟每个人拉屎速度不一样,0代表有的人蹲下就起来了
        sem.release()
    
    if __name__ == '__main__':
        sem=Semaphore(5)
        p_l=[]
        for i in range(13):
            p=Process(target=go_wc,args=(sem,'user%s' %i,))
            p.start()
            p_l.append(p)
    
        for i in p_l:
            i.join()
        print('============》')

    事件

    python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。
    
        事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
    
    clear:将“Flag”设置为False
    set:将“Flag”设置为True
     
    
    #_*_coding:utf-8_*_
    #!/usr/bin/env python
    
    from multiprocessing import Process,Event
    import time,random
    
    def car(e,n):
        while True:
            if not e.is_set(): #Flase
                print('33[31m红灯亮33[0m,car%s等着' %n)
                e.wait()
                print('33[32m车%s 看见绿灯亮了33[0m' %n)
                time.sleep(random.randint(3,6))
                if not e.is_set():
                    continue
                print('走你,car', n)
                break
    
    def police_car(e,n):
        while True:
            if not e.is_set():
                print('33[31m红灯亮33[0m,car%s等着' % n)
                e.wait(1)
                print('灯的是%s,警车走了,car %s' %(e.is_set(),n))
                break
    
    def traffic_lights(e,inverval):
        while True:
            time.sleep(inverval)
            if e.is_set():
                e.clear() #e.is_set() ---->False
            else:
                e.set()
    
    if __name__ == '__main__':
        e=Event()
        # for i in range(10):
        #     p=Process(target=car,args=(e,i,))
        #     p.start()
    
        for i in range(5):
            p = Process(target=police_car, args=(e, i,))
            p.start()
        t=Process(target=traffic_lights,args=(e,10))
        t.start()
  • 相关阅读:
    Android开发学习之路-插件安装、检查应用是否安装解决方案
    Android开发学习之路-自定义控件(天气趋势折线图)
    Android开发学习之路-记一次CSDN公开课
    Android开发学习之路-RecyclerView滑动删除和拖动排序
    Android开发学习之路-带文字的图片分享
    Android开发学习之路-Android N新特性-多窗口模式
    Android开发学习之路-Volley源码解析
    Android开发学习之路-Android Studio开发小技巧
    Android开发学习之路-提升用户体验小技巧
    Android开发学习之路-Android6.0运行时权限
  • 原文地址:https://www.cnblogs.com/wanghaohao/p/7444551.html
Copyright © 2011-2022 走看看