互斥锁与队列

互斥锁

问什么要有锁

规范运行顺序 保证数据安全

多个进程依次执行 将并发变成了串行  谁先抢到锁先执行 当这个程序遇到了io阻塞 会切换到其他进程 当运行到 加锁的代码发现他没有 就不会运行这个进程了 以为锁只有一个进程拥有 保证了结果  
注意锁必须要同一把

多用于 抢购 依次执行

互斥锁与join区别共同点? (面试题)

# 互斥锁与join区别共同点? (面试题)
# 共同点: 都是完成了进程之间的串行.
# 区别: join认为控制的进程串行,互斥锁是随机的抢占资源.保证了公平性

利用锁抢票的实列 进程之间的通信实例.

# 业务需求分析:
# 买票之前先要查票,必须经历的流程: 你在查票的同时,100个人也在查本此列票.  查票 并发 买串
# 买票时,你要先从服务端获取到票数,票数>0 ,买票,然后服务端票数减一. 中间肯定有网络延迟.

from multiprocessing import Process
from multiprocessing import Lock
import time
import json
import os
import random
# 多进程原则上是不能互相通信的,它们在内存级别数据隔离的.不代表磁盘上数据隔离.
# 它们可以共同操作一个文件.
def search():
    time.sleep(random.random())#默认0到1
    with open('db.json',encoding='utf-8',mode='r') as f1:
        dic=json.load(f1)
    print(f"剩余票数{dic['count']}")

def get():
    with open('db.json',encoding='utf-8',mode='r') as f1:
        dic = json.load(f1)
    time.sleep(random.randint(1,2))
    if dic['count']>0:
        dic['count']-=1
        with open('db.json',mode='w',encoding='utf-8')as f2:
            json.dump(dic,f2)
    else:print('没票了')

def task(lock):
    search()
    lock.acquire()#加锁
    get()
    lock.release()#解锁
if __name__ == '__main__':
    lock=Lock()#生成一把锁
    for i in range(5):#生成5个进程
        p=Process(target=task,args=((lock,)))
        p.start()#发起进程运行

进程之间的通信:

进程之间的通信:

 1. 基于文件+ 锁的形式: 效率低,麻烦.
 2. 基于队列: 推荐使用形式.
 3. 基于管道: 管道自己加锁, 底层可以会出现数据丢失损坏.

队列.

什么是队列

就是存在于内存中的一个容器,最大的一个特点; 队列的特性就是FIFO.完全支持先进先出的原则.

from multiprocessing import Queue
q = Queue(3)  #可以设置元素个数maxsize是默认参数 括号不填默认2147483647与系统有关
# q.put(func)#插入数据 可以插入对象与数据类型 当插入过多到达队列个数会夯住
# print(q.get())#读取队列数据 get一次读一次 单队列没数据了就会夯住

队列的特殊参数

# q.put(333,block=False)# 改成False 超过了设置数 不阻塞了 直接报错.
# q.put(333,timeout=3)  # 延时报错,超过三秒再put不进数据,就会报错.
# q.get(333,block=False)  # 改成False  取不出了 不阻塞了 直接报错.
# q.get(333,timeout=3)  # 等3秒还 取不出了 不阻塞了 直接报错.

进程之间的通信实例.

就是利用队列 容器

# 小米:抢手环4.预期发售10个.
# 有100个人去抢.
from multiprocessing import Process
import time
from multiprocessing import Queue
import os
def task(q):
    try:
        q.put(os.getpid(),block=False)#队列满了报错
    except Exception:
        return

if __name__ == '__main__':
    q=Queue(10)#同一个队列
    for i in range(50):
        p=Process(target=task,args=((q,)))
        p.start()
    for i in range(1,11):
        print(f'排名{i}号的,用户{q.get()}')

生产者消费者模型

本质 队列间通信

为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

多个进程实现并发的效果: 生产者消费者模型.

3个成员 生产者 消费者 容器

模型, 设计模式,归一化设计, 理论等等,教给你一个编程思路.如果以后遇到类似的情况,直接套用即可.

如果没有容器, 生产者与消费者强耦合性.不合理.所以我们要有一个容器,缓冲区.平衡了生产力与消费力.

什么是生产者

生产数据 把数据放在容器中 这个进程就是生产者

什么是消费者

在容器中取数据的进程 这个进程就是消费者

容器

就是缓冲区(队列).一个缓冲区,平衡了生产者和消费者的处理能力。.提高了效率

转载于:https://www.cnblogs.com/saoqiang/p/11377385.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值