python基础知识(十)并发编辑----(二)

(十)并发编辑----(二)

目录

(十)并发编辑----(二)

10.1信号量multiprocessing.Semaphore

10.2事件multiprocessing.Event

10.3队列multiprocessing.Queue


10.1信号量multiprocessing.Semaphore

锁:同一个代码被一个进程使用

信号量:同一个代码被n个进程使用

from multiprocessing import Semaphore
from multiprocessing import process
import time
def func(i,sem):
    sem.acquire()  # 获取钥匙
    print('\033[32m%s走进ktv\033[0m'%i)
    time.sleep(random.randint(1,5))
    print('%s走出ktv'%i)
    sem.release()  # 放回钥匙
if __name__ == '__main__':
    sem = Semaphore(2) #两把钥匙
    for i in range(10):
        p = Process(target=func,args=(i,sem))
        p.start()

10.2事件multiprocessing.Event

一个信号可以使所有的进程都进入阻塞状态也,可以控制所有的进程解除阻塞

set 和 clear:分别用来修改一个事件的状态 True或者False

is_set:用来查看一个事件的状态

wait 是依据事件的状态来决定自己是否在wait处阻塞 False阻塞 True不阻塞

 from multiprocessing import Event
一个事件被创建之后,默认是阻塞状态
e = Event()  # 创建了一个事件
print(e.is_set())   # 查看一个事件的状态,默认被设置成阻塞
e.set()      # 将这个事件的状态改为True
print(e.is_set())
e.wait()     # 是依据e.is_set()的值来决定是否阻塞的
print(123456)
e.clear()    # 将这个事件的状态改为False
print(e.is_set())
e.wait()     # 等待 事件的信号被变成True
print('*'*10)
'''
False
True
123456
False
'''

红绿灯问题

import time
import random
from multiprocessing import Event,Process
def cars(e,i):
    if not e.is_set():
        print('car%i在等待'%i)
        e.wait()    # 阻塞 直到得到一个 事件状态变成 True 的信号
    print('car%i通过' % i)

def light(e):
    while True:
        if e.is_set():
            e.clear()
            print('\033[31m红灯亮了\033[0m')
        else:
            e.set()
            print('\033[32m绿灯亮了\033[0m')
        time.sleep(2)

if __name__ == '__main__':
    e = Event()
    traffic = Process(target=light,args=(e,))
    traffic.start()
    for i in range(20):
        car = Process(target=cars, args=(e,i))
        car.start()
        time.sleep(random.random())

10.3队列multiprocessing.Queue

from multiprocessing import Queue,Process
def produce(q):
    q.put('hello')

def consume(q):
    print(q.get())

if __name__ == '__main__':
    q = Queue()
    p = Process(target=produce,args=(q,))
    p.start()
    c = Process(target=consume, args=(q,))
    c.start()

生产者消费者模型

简单版

def consumer(q, name):
    while True:
        food = q.get()
        if food is None:
            print('%s获取到了一个空' % name)
            break
        print('\033[31m%s消费了%s\033[0m' % (name, food))
        time.sleep(random.randint(1, 3))


def producer(name, food, q):
    for i in range(4):
        time.sleep(random.randint(1, 3))
        f = '%s生产了%s%s' % (name, food, i)
        print(f)
        q.put(f)


if __name__ == '__main__':
    q = Queue(20)
    p1 = Process(target=producer, args=('A', '包子', q))
    p2 = Process(target=producer, args=('B', '泔水', q))
    c1 = Process(target=consumer, args=(q, 'C'))
    c2 = Process(target=consumer, args=(q, 'D'))
    p1.start()
    p2.start()
    c1.start()
    c2.start()
    p1.join()
    p2.join()
    q.put(None)
    q.put(None)

升级版

在消费者这一端: 每次获取一个数据,处理一个数据,发送一个记号 : 标志一个数据被处理成功

在生产者这一端: 每一次生产一个数据, 且每一次生产的数据都放在队列中,在队列中刻上一个记号

当生产者全部生产完毕之后, join信号 : 已经停止生产数据了,且要等待之前被刻上的记号都被消费完,当数据都被处理完时,join阻塞结束

consumer中把所有的任务消耗完,producer端的join感知到,停止阻塞,所有的producer进程结束,主进程中的p.join结束,主进程中代码结束,守护进程(消费者的进程)结束

import time
import random
from multiprocessing import Process,JoinableQueue
def consumer(q,name):
    while True:
        food = q.get()
        print('\033[31m%s消费了%s\033[0m' % (name,food))
        time.sleep(random.randint(1,3))
        q.task_done()     # count - 1

def producer(name,food,q):
    for i in range(4):
        time.sleep(random.randint(1,3))
        f = '%s生产了%s%s'%(name,food,i)
        print(f)
        q.put(f)
    q.join()    # 阻塞  直到一个队列中的所有数据 全部被处理完毕

if __name__  == '__main__':
    q = JoinableQueue(20)
    p1 = Process(target=producer, args=('A', '包子', q))
    p2 = Process(target=producer, args=('B', '泔水', q))
    c1 = Process(target=consumer, args=(q, 'C'))
    c2 = Process(target=consumer, args=(q, 'D'))
    p1.start()
    p2.start()
    c1.daemon = True   # 设置为守护进程 主进程中的代码执行完毕之后,子进程自动结束
    c2.daemon = True
    c1.start()
    c2.start()
    p1.join()
    p2.join()      # 感知一个进程的结束

猜你喜欢

转载自blog.csdn.net/zeroooorez/article/details/91536226