---恢复内容开始---

了解知识点:

1、守护进程:

·什么是守护进程:

守护进程其实就是一个‘子进程’,守护即伴随,守护进程会伴随主进程的代码运行完毕后而死掉

·为何用守护进程:

当该子进程内的代码在父进程代码运行完毕后就没有存在的意义了,就应该将进程设置为守护进程,会在父进程代码结束后死掉

 from multiprocessing import Process

 import time,os

 def task(name):
print('%s is running'%name)
time.sleep(3) if __name__ == '__main__':
p1=Process(target=task,args=('守护进程',))
p2=Process(target=task,args=('正常的子进程',))
p1.daemon=True # 一定要放到p.start()之前
p1.start()
p2.start()
print('主')

守护进程举例

以下是守护进程会迷惑人的范例:

 #主进程代码运行完毕,守护进程就会结束
from multiprocessing import Process
import time
def foo():
print(123)
time.sleep(1)
print("end123") def bar():
print(456)
time.sleep(3)
print("end456") if __name__ == '__main__':
p1=Process(target=foo)
p2=Process(target=bar) p1.daemon=True
p1.start()
p2.start()
print("main-------") '''
main-------
456
enn456
''' '''
main-------
123
456
enn456
''' '''
123
main-------
456
end456
'''

2、互斥锁:

互斥锁:可以将要执行任务的部分代码(只涉及到修改共享数据的代码)变成串行

join:是要执行任务的所有代码整体串行

强调:必须是lock.acquire()一次,然后 lock.release()释放一次,才能继续lock.acquire(),不能连续的lock.acquire()。否者程序停在原地。
互斥锁vs join: 
大前提:二者的原理都是一样,都是将并发变成串行,从而保证有序(在多个程序共享一个资源时,为保证有序不乱,需将并发变成串行)
区别一:join是按照人为指定的顺序执行,而互斥锁是所以进程平等地竞争,谁先抢到谁执行
区别二:互斥锁可以让一部分代码(修改共享数据的代码)串行,而join只能将代码整体串行(详见抢票系统)
互斥锁
 from multiprocessing import Process,Lock
import json
import os
import time
import random def check():
time.sleep(1) # 模拟网路延迟
with open('db.txt','rt',encoding='utf-8') as f:
dic=json.load(f)
print('%s 查看到剩余票数 [%s]' %(os.getpid(),dic['count'])) def get():
with open('db.txt','rt',encoding='utf-8') as f:
dic=json.load(f)
time.sleep(2)
if dic['count'] > 0:
# 有票
dic['count']-=1
time.sleep(random.randint(1,3))
with open('db.txt','wt',encoding='utf-8') as f:
json.dump(dic,f)
print('%s 购票成功' %os.getpid())
else:
print('%s 没有余票' %os.getpid()) def task(mutex):
# 查票
check() #购票
mutex.acquire() # 互斥锁不能连续的acquire,必须是release以后才能重新acquire
get()
mutex.release() # with mutex:
# get() if __name__ == '__main__':
mutex=Lock()
for i in range(10):
p=Process(target=task,args=(mutex,))
p.start()
# p.join()

模拟抢票

3、IPC通信机制

进程之间通信必须找到一种介质,该介质必须满足
1、是所有进程共享的
2、必须是内存空间
附加:帮我们自动处理好锁的问题
 
a、   from multiprocessing import Manager(共享内存,但要自己解决锁的问题)
b、   IPC中的队列(Queue) 共享,内存,自动处理锁的问题(最常用)
c、   IPC中的管道(Pipe),共享,内存,需自己解决锁的问题

a、用Manager(了解知识点)

 from multiprocessing import Process,Manager,Lock
import time mutex=Lock() def task(dic,lock):
lock.acquire()
temp=dic['num']
time.sleep(0.1)
dic['num']=temp-1
lock.release() if __name__ == '__main__':
m=Manager()
dic=m.dict({'num':10}) l=[]
for i in range(10):
p=Process(target=task,args=(dic,mutex))
l.append(p)
p.start()
for p in l:
p.join()
print(dic)

b、用队列Queue

1)共享的空间

2)是内存空间

3)自动帮我们处理好锁定问题

 from multiprocessing import Queue
q=Queue(3) #设置队列中maxsize个数为三
q.put('first')
q.put({'second':None})
q.put('三')
# q.put(4) #阻塞。不报错,程序卡在原地等待队列中清出一个值。默认blok=True
print(q.get())
print(q.get())
print(q.get()) 强调:
1、队列用来存成进程之间沟通的消息,数据量不应该过大
2、maxsize的值超过的内存限制就变得毫无意义
 了解:
q=Queue(3)
q.put('first',block=False)
q.put('second',block=False)
q.put('third',block=False)
q.put('fourth',block=False) #报错 queue.Full q.put('first',block=True)
q.put('second',block=True)
q.put('third',block=True)
q.put('fourth',block=True,timeout=3) #等待3秒后若还进不去报错。注意timeout不能和block=False连用 q.get(block=False)
q.get(block=False)
q.get(block=False)
q.get(block=False) #报错 queue.Empty q.get(block=True)
q.get(block=True)
q.get(block=True)
q.get(block=True,timeout=2) #等待2秒后还取不出东西则报错。注意timeout不能和block=False连用

了解

4、生产者与消费者模型

该模型中包含两类重要的角色:
1、生产者:将负责造数据的任务比喻为生产者
2、消费者:接收生产者造出的数据来做进一步的处理,该类人物被比喻成消费者
 
实现生产者消费者模型三要素
1、生产者
2、消费者
3、队列
什么时候用该模型:
程序中出现明显的两类任何,一类任务是负责生产,另外一类任务是负责处理生产的数据的
 
该模型的好处:
1、实现了生产者与消费者解耦和
2、平衡了生产者的生产力与消费者的处理数据的能力
注意:生产者消费者模型是解决问题的思路不是技术。可以用进程和队列来实现,也可以用其他的来实现。
 from multiprocessing import JoinableQueue,Process
import time
import os
import random def producer(name,food,q):
for i in range(3):
res='%s%s' %(food,i)
time.sleep(random.randint(1,3))
# 往队列里丢
q.put(res)
print('\033[45m%s 生产了 %s\033[0m' %(name,res))
# q.put(None) def consumer(name,q):
while True:
#从队列里取走
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print('\033[46m%s 吃了 %s\033[0m' %(name,res))
q.task_done() if __name__ == '__main__':
q=JoinableQueue()
# 生产者们
p1=Process(target=producer,args=('egon','包子',q,))
p2=Process(target=producer,args=('杨军','泔水',q,))
p3=Process(target=producer,args=('猴老师','翔',q,))
# 消费者们
c1=Process(target=consumer,args=('Alex',q,))
c2=Process(target=consumer,args=('wupeiqidsb',q,))
c1.daemon=True
c2.daemon=True p1.start()
p2.start()
p3.start()
c1.start()
c2.start() p1.join()
p2.join()
p3.join()
q.join() #等待队列被取干净
# q.join() 结束意味着
# 主进程的代码运行完毕--->(生产者运行完毕)+队列中的数据也被取干净了->消费者没有存在的意义 # print('主')

Python中的生产者消费者模型的更多相关文章

  1. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

  2. python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)

    #######################总结######### 主要理解 锁      生产者消费者模型 解耦用的   队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...

  3. Python实现:生产者消费者模型(Producer Consumer Model)

    #!/usr/bin/env python #encoding:utf8 from Queue import Queue import random,threading,time #生产者类 clas ...

  4. Java 实现生产者 – 消费者模型

    转自:http://www.importnew.com/27063.html 考查Java的并发编程时,手写“生产者-消费者模型”是一个经典问题.有如下几个考点: 对Java并发模型的理解 对Java ...

  5. python生产者消费者模型

    业界用的比较广泛,多线程之间进行同步数据的方法,解决线程之间堵塞,互相不影响. server --> 生产者 client --> 消费者 在一个程序中实现又有生产者又有消费者 ,生产者不 ...

  6. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  7. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  8. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))

    昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...

  9. python网络编程--进程(方法和通信),锁, 队列,生产者消费者模型

    1.进程 正在进行的一个过程或者说一个任务.负责执行任务的是cpu 进程(Process: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在 ...

随机推荐

  1. 【python之路32】python异常处理

    一.捕获异常 1.try  except #!usr/bin/env python # -*- coding:utf-8 -*- num = input("请输入一个数字:") t ...

  2. MAC+iTerm定制目录显示颜色和提示符

    知道该如何定制ls时各种类型文件(unix下所有的都是file..)的颜色了. 很简单,就是在.bash_profile下加了三行. export CLICOLOR=1 export LSCOLORS ...

  3. hdu 1166 敌兵布阵(线段树区间求和)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. 【Scala学习笔记】一、函数式编程的思想

    1. 函数是头等值.     在函数编程中,函数也是值,与整数和字符串处于同一地位.函数可以像变量一样被创建,修改,并当成变量一样传递,返回或是在函数中嵌套函数. 函数可以当做参数传递给其他函数.   ...

  5. linux把普通用户添加到sudo组

    一.linux下把普通用户添加到sudo组的方式: 1. root权限下, 先cd到/etc目录下 2. 由于sudoers文件为只读权限,所以需要添加写入权限,chmod u+w sudoers 3 ...

  6. IO流10 --- 缓冲流(字节型)实现非文本文件的复制 --- 技术搬运工(尚硅谷)

    字节型缓冲流,BufferedOutputStream默认缓冲区大小 8192字节byte,满了自动flush() @Test public void test6(){ File srcFile = ...

  7. Leetcode15.3Sum三数之和

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...

  8. 基于 DataLakeAnalytics 的数据湖实践

    随着软硬件各方面条件的成熟,数据湖(Data Lake)已经越来越受到各大企业的青睐, 与传统的数仓实践不一样的是,数据湖不需要专门的“入仓”的过程,数据在哪里,我们就从哪里读取数据进行分析.这样的好 ...

  9. 直白介绍卷积神经网络(CNN)【转】

    英文地址:https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/ 中文译文:http://mp.weixin.qq.com/s ...

  10. 图文结合深入理解 JS 中的 this 值

    图文结合深入理解 JS 中的 this 值 在 JS 中最常见的莫过于函数了,在函数(方法)中 this 的出现频率特别高,那么 this 到底是什么呢,今天就和大家一起学习总结一下 JS 中的 th ...