Python学习之路并发编程--信号量、事件、队列及生产消费模型

1. 信号量  

  对于多进程来说,多个进程同时修改数据,就可能出现安全隐患,所以引入了锁,这一机制,但锁只能有一把来控制一个的开关,当你需要几把锁的时候,就可能用到信号量的概念。他是用了锁的原理,内置了一个计数器,在同一时内,只能有指定数量的进程来执行某一段被控制的代码。

import time,random
from multiprocessing import Process,Semaphore

def singing(i,sem):
    ‘‘‘
    :param i: 随机生成20个数的值
    :param sem:生成的信号量
    :return:None
    ‘‘‘
    sem.acquire()#获得锁
    print(‘%s is coming ‘%i)
    time.sleep(random.randint(10,20))#随机在10秒至20秒中停顿
    print(‘%s is going out‘%i)
    sem.release()#释放锁

if __name__ == ‘__main__‘:
    sem = Semaphore(4)#生成4个锁
    for i in range(20):
        p = Process(target=singing,args=(i,sem))
        p.start()

2. 事件

  事件是通过一个信号来控制多个进程的同时执行或阻塞,当一个事件被创建的时候默认是阻塞状态,但不影响进程的执行,当遇到 even.wait() 方法时,才会阻塞。

# set 和 clear
#      分别用来修改一个事件的状态 True或者False
# is_set 用来查看一个事件的状态
# wait 是依据事件的状态来决定自己是否在wait处阻塞
#      False阻塞 True不阻塞

  下面是一个红绿灯的问题。

import time
import random
from multiprocessing import Event,Process

def cars(e,i):
    ‘‘‘
    一个判断车是否通过的函数
    :param e: 传入一个事件
    :param i: 生成的车几
    :return: None
    ‘‘‘
    if not e.is_set():
        print(‘\033[0;31;40mcar %s 在等待~\033[0m‘%i)
        e.wait()
    print(‘\033[32;40mcar %s 通过~\033[0m‘%i)

def light(e):
    ‘‘‘
    控制红绿灯的切换
    :param e: 传入事件
    :return: None
    ‘‘‘
    while True:
        if e.is_set():
            e.clear()
            print(‘\033[31m红灯亮了\033[0m‘)
            time.sleep(3)
        else:
            e.set()
            print(‘\033[32m绿灯亮了\033[0m‘)
            time.sleep(5)

if __name__ == ‘__main__‘:
    e = Event()
    traffic = Process(target=light,args=(e,))
    traffic.start()
    time.sleep(1)
    for i in range(random.randint(5,10)):
        car = Process(target=cars,args=(e,i))
        car.start()
        time.sleep(random.randint(1,3))

3. 队列

  队列 Queue 中只有少数几个方法,

    # put  当队列满的时候阻塞等待队列有空位置
    # get  当队列空的时候阻塞等待队列有数据
    # full empty 不完全准确

  full 和 empty 不准一原因在于,如果队列回答主程序时,同时进程又对队列进行了操作,这个就会造成数据的错误。

4. 用 JoinableQueue 来处理生产者和消费者模型

import time
import random
from multiprocessing import Process,JoinableQueue

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()    # 阻塞  直到一个队列中的所有数据 全部被处理完毕

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

if __name__  == ‘__main__‘:
    q = JoinableQueue(20)
    p1 = Process(target=producer,args=(‘eli‘,‘dumpling‘,q))
    p2 = Process(target=producer, args=(‘tom‘,‘noodle‘, q))
    c1 = Process(target=consumer, args=(q,‘mike‘))
    c2 = Process(target=consumer, args=(q,‘johan‘))
    p1.start()
    p2.start()

    c1.daemon = True   # 设置为守护进程 主进程中的代码执行完毕之后,子进程自动结束
    c2.daemon = True

    c1.start()
    c2.start()
    p1.join()
    p2.join()      # 感知一个进程的结束

  觉得最好的点就是用到了守护进程(当主进程的程序执行完成时,子进程也随之结束)。

原文地址:https://www.cnblogs.com/YS-0717/p/9742137.html

时间: 2024-07-31 18:57:31

Python学习之路并发编程--信号量、事件、队列及生产消费模型的相关文章

python学习笔记-Day11 (线程、进程、queue队列、生产消费模型、携程)

线程使用 ###方式一 import threading def f1(arg): print(arg) t = threading.Thread(target=f1, args=(123,)) t.start() # start会调用run方法执行 # t是threading.Thread类的一个对象 # t.start()就会以线程的方式执行函数,可以使用pycharm ctrl选择start方法 # 找到Thread类的start方法,在start方法的注释中就已经写明,会去调用run()

python学习之路网络编程篇(第五篇)-续篇

Python堡垒机实现之基础知识 一般的堡垒机必须要具备以下5个基本功能: 1.权限控制 2.执行命令 3.上传下载文件 4.远程登录 5.记录操作 权限控制 说明:根据不同的登录用户分配不同的可管理的主机组.(再细分的权限就是根据不同的用户控制可在主机上执行的命令,一般不会限制的这么严格) 思路:使用数据库创建用户表,表字段有ID.用户名.密码.所属组,再创建主机表,表字段有ID,主机IP,所属组.其中用户表中的所属组和主机表中的所属组相对应,这样就能把两张表关联起来.当用户登录的时候就可以根

《Python学习之路 -- 网络编程》

在前面已经提到过,互联网的本质就是一堆协议,协议就是标准,比如全世界人通信的标准是英语,所有的计算机都学会了互联网协议,那么所有的计算机就可以按照统一的标准去收发信息完成通信了. 作为普通开发人员的我们,写的软件/程序都是处于应用层上的,然而,想要让软件接入互联网,就必须得通过传输层,也就是必须遵循TCP协议或者UDP协议.这是两个非常复杂的协议,如果遵循原生的协议,那么必然会大大降低效率,所以就有了socket抽象层的概念.socket是应用层与TCP/IP协议族通信的软件抽象层,它是一组接口

python学习之路网络编程篇(第一篇)

新课程知识的引入:python作用域 #python中无块级别作用域 if 1 == 1 : name = 'alex' print(name) for i in range(10): name = i print(name) #python中以函数为作用域 def func(): name = 'alex' print(name) #程序执行结果 # Traceback (most recent call last): # File "D:/PythonS13/Day10/С????1_pyt

python学习之路网络编程篇(第五篇)

paramiko简介 paramiko 是基于Python实现的SSH2远程安装连接,支持认证及秘钥方式.可以实现远程命令执行.文件传输.中间SSH代理等功能. paramiko安装 #!/bin/bash #install indepence package cd /data/soft wget https://www.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.6.tar.gz yum -y install gcc python-devel

Python学习之路3?编程风格

语句和语法 #   表示注释掉的内容 \    续行 1 print("yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy2 yyyyyyyyyyyyyyyyyyyyyyy") ;    分号:同一行放置多个语句以分号作为分割符 1 print('cyy');print('zzl') 2 3 输出结果: 4 cyy 5 zzl 语句(代码块)用缩进方式体现不同的代码级别,建议用4个空格(不要用tab) python文件以模块的方式组织,编写一个.py结尾的文件实际上

Python学习之路--网络编程

由于不同机器上的程序要通信,才产生了网络 C/S Client/Server 客户端/服务端 服务端 一直运行 等待服务别人 客户端 寻求服务的时候 才请求服务 B/S Browser/Server 浏览器/服务器 b/s架构是c/s架构的一种 实现通信上有全球唯一的MAC地址 网卡和网线 网卡 通过ip地址就能找到对应的MAC地址  ARP协议 交换机 ---- 多台机器之间的通信问题 广播风暴 网关  局域网中的机器想要访问局域网外的机器,需要通过网关访问 IP地址 和 子网掩码 按位与 

Python学习之路【第一篇】-Python简介和基础入门

1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是一种开发语言,而且已经进阶到主流的二十多种开发语言的top 5(数据源自最新的TIOBE排行榜). 来头不小啊!二十多种主流的开发语言,我该从哪一个开始呢?人生苦短,let‘s python! 1.2 Python的由来和发展趋势 Python的前世源自鼻祖“龟叔”.1989年,吉多·范罗苏姆(Gu

Python学习之路——强力推荐的Python学习资料

资料一:程序媛想事儿(Alexia)总结 Python是一种面向对象.直译式计算机程序设计语言.它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用縮进来定义语句块.与Scheme.Ruby.Perl.Tcl等动态语言一样,Python具备垃圾回收功能,能够自动管理内存使用.它经常被当作脚本语言用于处理系统管理任务和网络程序编写,然而它也非常适合完成各种高级任务. Python上手虽然容易,但与其它任何语言一样要学好Python并非一日之功.我的Pyth