• 共享数据, 信号量(了解),事件(了解)


    进程间通信应该尽量避免使用本节所讲的共享数据的方式
    进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的 虽然进程间数据独立,但可以通过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()
  • 相关阅读:
    13.Query for Null or Missing Fields-官方文档摘录
    海南IT互联网招聘数据简单分析
    Mongo Spark Connector中的分区器(一)
    一、Golang中的反射基本使用
    Golang中的sync.Pool对象
    Golang中的内置函数
    golang单元测试简述
    Spark Streaming数据限流简述
    Golang中类面向对象特性
    在Docker中跑Hadoop与镜像制作
  • 原文地址:https://www.cnblogs.com/wanghaohao/p/7444551.html
Copyright © 2020-2023  润新知