day29并发编程

1、进程锁

一、使用锁维护执行顺序
代码:
from multiprocessing import Process,Lock
import os
import time def task(i,lock):
# 开始上锁
lock.acquire()
print('第%s个:进程id号:%s进来了'%(i,os.getpid()))
time.sleep(3)
print('第%s个:进程ID号:%s走了'%(i,os.getpid()))
# 释放锁
lock.release() if __name__ == '__main__':
lock = Lock() # 共用一把锁
for i in range(5):
p = Process(target=task,args=(i,lock))
p.start()
# 上面这种情况虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全。

2、进程间数据隔离

一、进程之间数据是互不影响的
代码:
from multiprocessing import Process
n = 10 def task():
global n
n = 100
print('task:',n) if __name__ == '__main__':
# task()
p =Process(target=task)
p.start()
print('main',n)
# 注:加上task()输出结果为main 10,task: 100
# 不加task()输出结果为main 10,task: 100

3、Queue队列的使用

一、方法介绍:
1.Queue([maxsize]):创建共享的进程队列。maxsize是队列允许的最大项数。如果不写参数的话。
2.q.get([block[,timeout]]):返回q中的一个项目。如果为空,此方法将造成堵塞,直到有可用项目为止。
3.q.get_nnowait():和q.get(False)方法一样,作用是控制堵塞:# q.put('my is handsome4', block=False)
4.q.put(item[,block[,timeout]]):将item放入队列
5.q.qsize():返回队列中目前项目的正确数量。
6.q.empty():如果队列里面放数据返回Fales,不放数据返回True,结果可能是不可靠的。
7.q.full():如果队列已满,返回True,结果可能是不可靠的
二、方法里的参数
1.如:q.get( [ block [ ,timeout ] ] ):返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。block用于控制阻塞行为,默认为True. 如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。timeout是可选超时时间,用在阻塞模式中。如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。
2.用法如下:
代码:
from multiprocessing import Queue if __name__ == '__main__':
q = Queue(3) # 拿到一个空队列的对象
q.put('my is handsome1') # 把数据放到队列中
q.put('my is handsome2')
q.put('my is handsome3')
q.put('my is handsome4', block=False) # block用于控制阻塞行为,如果设置为False,将引发Queue.Empty异常
q.put('my is handsome4', timeout=2) # 如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。
q.put_nowait('my is handsome4') # 跟block方法一样的效果 print(q.get())
print(q.get()) # 返回q中的数据
print(q.get())
print(q.get(timeout=2)) # 也有队列的属性
print(q.get_nowait())
print(q.qsize()) # 返回队列中目前项目的正确数量
print(q.empty()) # 队列里面放数据返回Fales,不放数据返回True,结果可能是不可靠的
print(q.full()) # 队列已满,返回True,结果可能是不可靠的

4、解决进程间数据隔离问题

代码:
from multiprocessing import Process,Queue def task(queue):
queue.put('hello') # 通过q.get()拿到的数据
print('hi') # 通过子进程得到的结果 if __name__ == '__main__':
q = Queue()
p =Process(target=task,args=(q, ))
p.start() print(q.get()) # 通过主进程拿到“hello”数据
输出结果:hi ,hello

5、生产者消费者模型代码演示

​ 在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

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

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

5.2、什么是生产者消费者模式

    生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

5.3、代码演示

版本1:取完包子遇到阻塞,直到有可用项目为止

from multiprocessing import Process, Queue
import os
import time # 版本1:取完包子遇到阻塞,直到有可用项目为止
def producer(queue):
for i in range(5):
data = ('%s:蒸了第%s个包子' % (os.getpid(), i))
print(data)
queue.put(data) # 把数据放入队列 def consumer(queue):
while True:
data = queue.get()
print(data) if __name__ == '__main__':
q = Queue()
p = Process(target=producer, args=(q,))
p.start() p1 = Process(target=consumer, args=(q,))
p1.start()

版本2:

def producer(queue):
for i in range(5):
data = ('%s:蒸了第%s个包子' % (os.getpid(), i))
print(data)
queue.put(data) # 把数据放入队列
queue.put(None) def consumer(queue):
while True:
data = queue.get()
if not data:break
time.sleep(1)
print(data) if __name__ == '__main__':
q = Queue()
p = Process(target=producer, args=(q,))
p.start() p1 = Process(target=consumer, args=(q,))
p1.start()

版本3: 多生产者,少消费者

def producer(queue,food):
for i in range(5):
data = ('%s:生产了第%s个%s' % (os.getpid(), i,food))
# print(data)
queue.put(data) # 把数据放入队列 def consumer(queue):
while True:
data = queue.get()
if not data:break
time.sleep(0.2)
print(data) if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer, args=(q,'馒头'))
p2 = Process(target=producer, args=(q,'花卷'))
p3 = Process(target=producer, args=(q,'烧麦'))
p1.start()
p2.start()
p3.start() p4 = Process(target=consumer, args=(q,))
p5 = Process(target=consumer, args=(q,))
p4.start()
p5.start()
p1.join() # 加上join
p2.join() # 加上join
p3.join() # 加上join
q.put(None) # 这里放几个取决于消费者有几个
q.put(None)
print('=====>')

版本四:最终版本:消费者多,生产者少

def producer(queue,food):
for i in range(5):
data = ('%s:生产了第%s个%s' % (os.getpid(), i,food))
# print(data)
queue.put('第%s个%s'%(i,food)) # 把数据放入队列 def consumer(queue,name):
while True:
try:
data = queue.get(timeout=3)
if not data:break
time.sleep(0.2)
print('消费者:%s,消费了:%s'%(name,data))
except Exception as e:
print(e)
break if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer, args=(q,'馒头'))
p2 = Process(target=producer, args=(q,'花卷'))
p3 = Process(target=producer, args=(q,'烧麦'))
p1.start()
p2.start()
p3.start() p4 = Process(target=consumer, args=(q,'迪迦'))
p5 = Process(target=consumer, args=(q,'琦玉'))
p6 = Process(target=consumer, args=(q,'悟空'))
p7 = Process(target=consumer, args=(q,'路飞'))
p4.start()
p5.start()
p6.start()
p7.start()
p1.join() # 加上join
p2.join() # 加上join
p3.join() # 加上join
q.put(None) # 这里放几个取决于消费者有几个
q.put(None)
print('=====>')

day29并发编程的更多相关文章

  1. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  2. 伪共享(false sharing),并发编程无声的性能杀手

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...

  3. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  4. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  5. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  6. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  7. 【Java并发编程实战】-----“J.U.C”:Exchanger

    前面介绍了三个同步辅助类:CyclicBarrier.Barrier.Phaser,这篇博客介绍最后一个:Exchanger.JDK API是这样介绍的:可以在对中对元素进行配对和交换的线程的同步点. ...

  8. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  9. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

随机推荐

  1. 回文链表 牛客网 程序员面试金典 C++ Python

    回文链表 牛客网 程序员面试金典  C++ Python 题目描述 请编写一个函数,检查链表是否为回文. 给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文. 测试样例 ...

  2. v3

    #include <iostream> #include <time.h> #include "map" #include "stdio.h&qu ...

  3. 第07课 OpenGL 光照和键盘(1)

    光照和键盘控制: 在这一课里,我们将添加光照和键盘控制,它让程序看起来更美观. 这一课我会教您如何使用三种不同的纹理滤波方式.教您如何使用键盘来移动场景中的对象,还会教您在OpenGL场景中应用简单的 ...

  4. git安装心得

    每天码代码打卡任务,老师需要我们提交链接,这就需要我们把自己打的代码文件上传到GitHub上来,以此获得链接. 自己是一个新人,安装git也是什么都不懂(跟着网上的教程也总是能出错) 安装正常操作:h ...

  5. 【浏览器】聊聊DOM

    [浏览器]聊聊DOM 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 说明 作为前端开发,在以前的工作中大多是和DOM打交道,到 ...

  6. 攻防世界 WEB 高手进阶区 PHP2 Writeup

    攻防世界 WEB 高手进阶区 PHP2 Writeup 题目介绍 题目考点 url 二次解码 index.phps 文件(第一次使用dirsearch可能扫不到,需要加到工具字典里) php 简单语法 ...

  7. Code Runner,率先支持刚发布的 Visual Studio 2022!

    Visual Studio 被不少网友成为"宇宙第一IDE".但是,我写✍ PHP.Java 和 C#,也都是用的 VS Code. 我所在的组,是 Visual Studio C ...

  8. Go语言核心36讲(Go语言实战与应用一)--学习笔记

    23 | 测试的基本规则和流程 (上) 在接下来的日子里,我将带你去学习在 Go 语言编程进阶的道路上,必须掌握的附加知识,比如:Go 程序测试.程序监测,以及 Go 语言标准库中各种常用代码包的正确 ...

  9. vm扩展磁盘容量后不能启动

    主要原因是,新添加的磁盘空间没有分配,系统识别不出来,导致不能开机. 解决方法: 找到虚拟机的文件路径地址,默认是C:\Users\用户名\Documents\Virtual Machines\Cen ...

  10. 1. 处理静态资源 2. controller如何接受请求得参数 3. 如何把controller得数据保存到view. 4. 在controller如何完成重定向到指定路径 5. controller返回json数据

    1. 1. 处理静态资源2. controller如何接受请求得参数3. 如何把controller得数据保存到view.4. 在controller如何完成重定向到指定路径5. controller ...