专栏首页Python 学习day38(多进程) - 信号量、事件、进程队列(进程之间的通信)
原创

day38(多进程) - 信号量、事件、进程队列(进程之间的通信)

1.进程信号量.py

from multiprocessing import Process
from multiprocessing import Semaphore
import time
import random


def action(element, sem):
    # 控制只有 4 个进程在操作
    # 与 Lock() 一样上锁
    sem.acquire()
    print(element, '进到函数里来了')
    time.sleep(random.randint(3, 5))
    print(element, '从函数里面出来了')
    sem.release()


if __name__ == '__main__':
    p_list = []
    # 只允许 5个 进程同时操作
    sem_obj = Semaphore(5)
    for i in range(1, 21):
        p_obj = Process(target=action, args=(i, sem_obj))
        p_obj.start()
        p_list.append(p_obj)
    # 示例守护进程
    for p in p_list:
        p.join()

2.进程事件.py

# 关于 wait() 进程动态阻塞

# wait() 的阻塞状态是动态的

# 进程 A 将 event.set() 之后,进程 B 将立即继续执行

# 进程 A 将 event.clear()之后,进程 B 遇到 wait() 立即进入阻塞

from multiprocessing import Event
from multiprocessing import Process
import time
import random

"""
主进程的事件对象传递到多个函数进程内,
就可以对这些进程做控制
"""


# event = Event()
# 事件的默认状态是 False
# print(event.is_set())

"""
wait() 的阻塞状态是动态的
进程 A 将 event.set() 之后,进程 B 将立即继续执行
进程 A 将 event.clear()之后,进程 B 遇到 wait() 立即进入阻塞
"""


# event 的状态是 False 的时候,会阻塞,不执行下面的代码
# event 的状态是 True 的时候才会执行 wait() 下面的代码
# event.wait()

# 将 event 态改成 True
# event.set()
# print(event.is_set())

# 将 event 状态改成 False
# event.clear()
# print(event.is_set())

# 模拟红绿灯,设置事件的阻塞状态
def traffic_light(event):
    while 1:
        # 事件的默认状态是 False
        print('>>>红灯亮了<<<')
        time.sleep(10)
        event.set()
        print('===绿灯亮了===')
        time.sleep(10)
        event.clear()


# 模拟车辆
def cars_condition(event, car_num):
    # 模拟绿灯
    if event.is_set():
        print(car_num, '===过去了===')
    else:
        print(car_num, '>>>在等待<<<')
        event.wait()
        # print(car_num, '解除等待')
        time.sleep(random.randint(1, 5))
        print('刚才在等待的', car_num, '===过去了===')


if __name__ == '__main__':
    # 设置一个全局的事件,控制进程之间的阻塞
    event_obj = Event()
    # 一个进程用来模拟红绿灯,设置事件阻塞
    p_light = Process(target=traffic_light, args=(event_obj,))
    p_light.start()

    for num in range(1, 101):
        # 随机来车辆
        time.sleep(random.randint(1, 3))
        p_car = Process(target=cars_condition, args=(event_obj, num))
        p_car.start()

3.生产者消费者队列模型

# 队列是全局的

# 注意程序的 join() 和 daemon

# 生产者结束,主程序结束

# 主程序结束,消费者结束

# .put(),将生产的数据放进全局队列

# .get(),从队列中拿数据

# 拿一个队列中就少一个

# 先放进队列的数据,就先被拿出来

from multiprocessing import JoinableQueue
from multiprocessing import Process
import time
import random


def creator(role, queue):
    for num in range(1, 6):
        time.sleep(random.randint(1, 3))
        content = role + '创造了数据' + str(num)
        print('>>>', content, '<<<')
        # .put(),将生产的数据放进全局队列
        queue.put(content)


def customer(role, queue):
    while 1:
        # .get(),从队列中拿数据
        # 拿一个队列中就少一个
        # 先放进队列的数据,就先被拿出来
        queue_content = queue.get()
        print('===', role, '拿到了', queue_content, '===')
        # queue.task_done()


if __name__ == '__main__':
    # 队列是全局的,在不同进程之间可传递参数
    que = JoinableQueue()
    # 生产者进程
    creator_1 = Process(target=creator, args=('生产者1', que))
    creator_2 = Process(target=creator, args=('生产者2', que))
    creator_1.start()
    creator_2.start()

    # 消费者进程
    customer_1 = Process(target=customer, args=('消费者1', que))
    customer_2 = Process(target=customer, args=('消费者2', que))

    # 消费者随着主程序的结束而结束
    customer_1.daemon = True
    customer_2.daemon = True
    customer_1.start()
    customer_2.start()

    # 主程序在这里阻塞生产者程序的结束而结束
    # 不能写在上面,否则程序阻塞,消费者就阻塞不执行了
    creator_1.join()
    creator_2.join()
    
    # 主进程给消费者一点时间消费完全部的队列数据
    # 否则消费者数据还没消费完就跟着主进程结束了
    time.sleep(2)
    
    """
    生产者结束,主程序结束
    主程序结束,消费者结束
    """

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • day37(多进程)- 多进程、守护进程、进程锁

    # obj.start() 实际上是用的 run() 方法 # 但是对象不能直接调用 run() 方法 # 直接调用就立即执行,成了单线程 ...

    少年包青菜
  • day116-Flask的CBV&session高级&Form&DBUtils数据库连接工具

    少年包青菜
  • day102-day104-Linux基本命令

    <><><><><><><><><><><><><><><><><><><><>分割线<><><><><><><><><><><><><><><><><><><...

    少年包青菜
  • 中国工业互联网发展历程

    导读:工业互联网并不是空降的概念,从其发展历程来看,经历了从工业控制系统、到传感网、物联网再到现在的工业互联网。普遍来讲,无论国内还是国外,工业互联网本身的研...

    钱塘数据
  • [快学Python3]Sets(集合)

    概述 set是Python的基本数据类型,它有可变集合(set()) 和不可变集合(frozenset)两种,在本节中,我们主要讲解set的使用方法。set和d...

    苦叶子
  • 那些年犯过的错

        应该是11年还在人人的时候,那段时间主要工作都是纯考验技术的活儿。那时候离职人多。我一个人承担了原来4个团队的工作。白天各路产品来找。我要利用晚上的时间...

    静儿
  • iOS开发UI篇--iOS动画(Core Animation)总结

    IOS 动画主要是指Core Animation框架。官方使用文档地址为:Core Animation Guide。 Core Animation是IOS和OS...

    楚阳
  • 超实用的设计师个人品牌打造指南

    动画早就不是早期人们印象中的低龄向玩物了,从早年的卢卡斯影业到今天的工业光魔,动画技术证明了它可以实现无限的可能性;从70年代的高达、EVA到之后的宫崎骏、皮克...

    前朝楚水
  • 洞见 | 李飞飞与盖茨夫人对话人工智能:有了多样性行业才能健康发展AI

    梅琳达和李飞飞 AI科技评论按:虽然人工智能是当下最火热的话题,但它却遇到了多样性问题,业界推动该技术前进的人大都拥有相同的背景。对李飞飞来说,这样的情况令人担...

    AI科技评论
  • 论Spring中循环依赖的正确性与Bean注入的顺序关系

    最近在做项目时候遇到一个奇葩问题,就是bean依赖注入的正确性与bean直接注入的顺序有关系,但是正常情况下明明是和顺序没关系的啊,究竟啥情况那,不急,让我一一...

    加多

扫码关注云+社区

领取腾讯云代金券