day34 python学习 守护进程,线程,互斥锁,信号量,生产者消费者模型,
六 守护线程
无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁
需要强调的是:运行完毕并非终止运行
#1.对主进程来说,运行完毕指的是主进程代码运行完毕 #2.对主线程来说,运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
详细解释:
#1 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束, #2 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,
而进程必须保证非守护线程都运行完毕后才能结束。
守护进程的应用场景
# 举例说明守护进程的应用场景:
# 假设有两个任务要干,要玩出并发的效果,使用进程的话可以让主进程
# 执行一个任务,然后开启一个子进程执行一个任务。
#
# 如果这两个任务毫无关系,那么就像上面这么做就可以
# 如果主进程的任务在执行完毕后,子进程的任务没有存在的意义了
# 那么该子进程应该在开启之前就被设置成守护进程
例子
#守护进程的例子
from multiprocessing import Process
import os,time,random
def task():
print('%s is runing'%(os.getpid(),))
time.sleep(2)
print('%s is done'%(os.getpid()))
def func():
print('%s is runing'%(os.getpid(),))
time.sleep(2)
print('%s is done'%(os.getpid()))
if __name__ == '__main__':
p1=Process(target=task,)
p2 = Process(target=func,)
p1.daemon=True #1、必须在p.start()之前 2:守护进程不能开启子进程
p1.start()
p2.start()
print('zhu')
#结果如下,可以看到被守护的进程没有执行出,因为主进程中的代码执行完了
# ,所以被守护的进程被回收了,然而主进程等到非守护进程则继续执行完毕,才会结束进程
"""zhu
10024 is runing
10024 is done"""
#守护线程的例子
from threading import Thread
import os,time,random
def task():
print('%s is run'%(os.getpid(),))
time.sleep(2)
print('%s is do'%(os.getpid()))
def func():
print('%s is runing'%(os.getpid(),))
time.sleep(1)
print('%s is done'%(os.getpid()))
if __name__ == '__main__':
p1=Thread(target=task,)
p2 = Thread(target=func,)
p1.daemon=True #1、必须在p.start()之前
p1.start()
p2.start()
print('zhu')
#结果如下,守护线程等所有的非守护线程结束才结束才结束
# 11432 is run
# 11432 is runing
# zhu
# 11432 is done
守护线程
#迷惑人的例子迷惑人的例子
#主进程代码运行完毕,守护进程就会结束
from multiprocessing import Process
from threading import Thread
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-------") #打印该行则主进程代码结束,则守护进程p1应该被终止,
# 可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止
#打印结果如下,先打印 main 没有打印P1中的内容,因为主进程中的代码执行完了,所以守护进程就终止了
"""main-------
456
end456""" #
迷惑人的例子
迷惑人的例子迷惑人的例子
#主线程
from multiprocessing import Process
from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
print("end123") def bar():
print(456)
time.sleep(3)
print("end456") if __name__ == '__main__':
p1=Thread(target=foo)
p2 = Thread(target=bar) p1.daemon=True
p1.start()
p2.start()
print("main-------") #守护线程中主线程会等非守护线程执行完毕才完毕,
# 所以守护线程会等主线程完毕才停止执行,看到结果如下
"""123
456
main-------
end123
end456"""
迷惑人的例子,守护线程
互斥锁
锁通常被用来实现对共享资源的同步访问。为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用release方法释放锁:
from multiprocessing import Process,Lock
import time,random,os
def task(mutex):
#两种使用互斥锁的方式,方式一
# mutex.acquire()# 得到锁对象#其他的进程起来之后没有互斥锁对像,然后再这儿等着
# print('%s is runing'%(os.getpid()))
# time.sleep(random.randint(1,3))
# print('%s is run' % (os.getpid()))
# time.sleep(random.randint(1, 3))
# print('%s is done' % (os.getpid()))
# time.sleep(random.randint(1, 3))
# mutex.release() #释放锁对象,下一个进程获取互斥锁对象,其他的进程执行了
# # ,但是还是在等着抢锁对象
#方式二
with mutex:
print('%s is runing'%(os.getpid()))
time.sleep(random.randint(1,3))
print('%s is run' % (os.getpid()))
time.sleep(random.randint(1, 3))
print('%s is done' % (os.getpid()))
time.sleep(random.randint(1, 3))
if __name__ == '__main__':
mutex=Lock()
p1=Process(target=task,args=(mutex,))
p2 = Process(target=task, args=(mutex,))
p3 = Process(target=task, args=(mutex,))
p1.start()#进程都启动了,去抢互斥锁对象了,谁抢到了就先用,其他人继续等(进程已经开启了)然后着互相抢
p2.start()
p3.start()
print('主')
#打印结果如下,# 而且非 join的那种类型的,join是等上一个进程结束后在开启另一个进程
#而互斥锁是所有程序都起来了,但是有的在运行,有的在等待锁对象被释出来
"""主
9200 is runing
9200 is run
9200 is done
6940 is runing
6940 is run
6940 is done
8024 is runing
8024 is run
8024 is done
"""
from multiprocessing import Process,Lock
import json,time,os,random
def search():
with open('file','r',encoding='utf-8') as f:
dic=json.load(f)
print('%s还剩%s张票'%(os.getpid(),dic['dirct']))
time.sleep(random.randint(1,3))#在这里sleep可以判断手速跟网速,(即是点购买的速度)
def get():
with open('file','r',encoding='utf-8')as open_f:
dic=json.load(open_f)
if dic['dirct']>0:
# time.sleep(random.randint(1,3)) #
with open('file','w',encoding='utf-8') as ge_f:
dic['dirct']-=1
json.dump(dic,ge_f)
print('%s购票成功'%(os.getpid()))
def func(mutex):
search() #查票操作,这个是非需要枷锁的过程,所以U谁都可以查询
with mutex: #但是购买操作,谁抢到锁,谁买到票
get()
# mutex.acquire()#两种枷锁方式
# get()
# mutex.release() if __name__ == '__main__':
mutex=Lock() for i in range(20):
p1 = Process(target=func, args=(mutex,))#创建对象要在循环中,
# 否则就会走一遍就不再下一次了,
p1.start()
#p1.join()#不用join,否则就相当与串行的去执行了
print('zhu') #这里要记住用json的读取文件中的字典的时候,文件中字典要写成双引号的形式{"dirct": 0}
抢票程序,经典的LOck
互斥锁与join的区别:
# 而且非 join的那种类型的,join是等上一个进程结束后在开启另一个进程
#而互斥锁是所有程序都起来了,但是有的在运行,有的在等待锁对象被释出来,其他未抢到锁的进程继续抢锁
#进程池是从始至终都是在执行四个进程,而信号量是有100个任务的话就一下子开启100个任务
#但是只有10个抢到了锁,然后执行锁里边的内容在执行中,
from multiprocessing import Process,Semaphore
import time,os,random
def task(sm):
print(os.getpid())# 没有抢到锁的进程并发在执行这个代码
with sm:
print('%s 上厕所'%(os.getpid()))
time.sleep(random.randint(1,3)) if __name__ == '__main__':
sm=Semaphore(3)
for i in range(10):
p=Process(target=task,args=(sm,))#有10个进程在运行,在抢锁呢,抢到的执行锁里边的内容
# 这就是与进程池的不同
p.start()
信号量
信号量: 也是锁的概念(锁的数量是多把 而lock只有一把锁)
就是一个公司100个人在用电脑工作,但是公司只有10个打印机当要打印的时候就会抢打印机资源,其他时候正常工作,
#进程池是从始至终都是在执行四个进程,而信号量是有100个任务的话就一下子开启100个任务
#但是只有10个抢到了锁,然后执行锁里边的内容在执行中,
from multiprocessing import Process,Semaphore
import time,os,random
def task(sm):
with sm:
print('%s 上厕所'%(os.getpid()))
time.sleep(random.randint(1,3)) if __name__ == '__main__':
sm=Semaphore(3)
for i in range(10):
p=Process(target=task,args=(sm,))#有10个进程在运行,在抢锁呢,抢到的执行锁里边的内容
# 这就是与进程池的不同
p.start()
队列 Queue
平常引用队列 import queue
进程 queue 线程queue 引用方式 from mulitprocessing import Queue
from multiprocessing import Queue #进程队列
q=Queue(3) #设置队列的容量,也可以不设置
q.put(1)
q.put({'ss':1})
# q.put('sss')
# q.put([1,2,3]) #当放入的数据数量大于容量时,程序就会卡在这里,
print(q.get())
print(q.get())
print(q.get()) #当往外取得次数大于队列内部的数量,就会卡在这里一直往外取东西
# ,程序就会卡在这里,
堆栈
#堆栈
import queue
q=queue.LifoQueue(3) #先进后出
q.put({'a':1})
q.put('xxxxx')
q.put(3)
# q.put(4) print(q.get())
print(q.get())
print(q.get())
print(q.get())
堆栈,先进后出
优先级队列
#优先级队列
import queue
q=queue.PriorityQueue(3)
q.put((10,{'a':1})) #设置优先级,-1 为被取出优先级最高的
q.put((-1,'xxxxx'))
q.put((0,3))
# q.put(4) print(q.get())
print(q.get())
print(q.get())
print(q.get())
设置取出的优先级
生产者消费者模型*****
使用队列 实现解耦
from multiprocessing import Process,Queue
import time,os
def procducer(q):
for i in range(10):
res='baozi%s'%i
time.sleep(0.5)
q.put(res)
print('%s 生产了%s'%(os.getpid(),i)) def consumer(q):
while True:
res=q.get()
if res==None: #队列中取到None的时候就是队列中没有内容了,停止!
break
print('%s 吃 %s'%(os.getpid(),res))
time.sleep(2) if __name__ == '__main__':
q=Queue() #设置队列,可以让两个进程之间的是实现了解耦的功能(两个程序之间不用直接联系,有中介)
p=Process(target=procducer,args=(q,))
c = Process(target=consumer, args=(q,))
p.start() #生产者消费者并发的去执行
c.start() p.join()# 等待生产者生产完成
q.put(None) #将None放入队列中,作为消费者停止从队列中往外取内容的标志
print('zhu')
#升级版,
from multiprocessing import Process,Queue,JoinableQueue
import os,time,random
def productor(name,q):
for i in range(3):
res='%s %s'%(name,i)
q.put(res)
print('%s生产了%s %s'%(os.getpid(),name,i))
time.sleep(0.1) def consumer(q):
while True:
res=q.get()
if res==None:
break
print('%s 吃了 %s'%(os.getpid(),res))
time.sleep(random.randint(1,3)) if __name__ == '__main__':
q=Queue()
p1=Process(target=productor,args=('包子',q,))
p2 = Process(target=productor, args=('泔水', q,))
p3 = Process(target=productor, args=('狗粮', q,))
c1=Process(target=consumer,args=(q,))
c2=Process(target=consumer,args=(q,))
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
q.put(None) #有两个消费者就要用两个None 让消费之吃到None 时结束进程
q.put(None)
print('zhu') #使用JoinableQueue
from multiprocessing import Process,Queue,JoinableQueue
import os,time,random
def productor(name,q):
for i in range(3):
res='%s %s'%(name,i)
q.put(res)
print('%s生产了%s %s'%(os.getpid(),name,i))
time.sleep(0.1) def consumer(q):
while True:
res=q.get()
if res==None:
break
print('%s 吃了 %s'%(os.getpid(),res))
time.sleep(random.randint(1,3)) if __name__ == '__main__':
q=JoinableQueue()
p1=Process(target=productor,args=('包子',q,))
p2 = Process(target=productor, args=('泔水', q,))
p3 = Process(target=productor, args=('狗粮', q,))
c1=Process(target=consumer,args=(q,))
c2=Process(target=consumer,args=(q,))
p1.start()
p2.start()
p3.start()
c1.daemon=True #这样设置可以让消费者成为守护进程,
# 当主进程结束之后就可以让子进程(消费者)结束
c2.daemon=True
c1.start()
c2.start()
p1.join()
p2.join()
p3.join()
print('zhu')
生产者消费者升级版
day34 python学习 守护进程,线程,互斥锁,信号量,生产者消费者模型,的更多相关文章
- POSIX信号量与互斥锁实现生产者消费者模型
posix信号量 Link with -lpthread. sem_t *sem_open(const char *name, int oflag);//打开POSIX信号量 sem_t *sem_o ...
- python并发编程之守护进程、互斥锁以及生产者和消费者模型
一.守护进程 主进程创建守护进程 守护进程其实就是'子进程' 一.守护进程内无法在开启子进程,否则会报错二.进程之间代码是相互独立的,主进程代码运行完毕,守护进程也会随机结束 守护进程简单实例: fr ...
- 并发编程(二)——利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道
Process类与开启进程.守护进程.互斥锁 一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模 ...
- [并发编程 - socketserver模块实现并发、[进程查看父子进程pid、僵尸进程、孤儿进程、守护进程、互斥锁、队列、生产者消费者模型]
[并发编程 - socketserver模块实现并发.[进程查看父子进程pid.僵尸进程.孤儿进程.守护进程.互斥锁.队列.生产者消费者模型] socketserver模块实现并发 基于tcp的套接字 ...
- day35 守护进程、互斥锁、IPC
day35 守护进程.互斥锁.IPC 1.守护进程 # 守护进程:当父进程执行完毕后,设置的守护进程也会跟着结束# 当一个进程被设置为守护进程后,其不能再产生子进程 from multiproces ...
- 4、网络并发编程--僵尸进程、孤儿进程、守护进程、互斥锁、消息队列、IPC机制、生产者消费者模型、线程理论与实操
昨日内容回顾 操作系统发展史 1.穿孔卡片 CPU利用率极低 2.联机批处理系统 CPU效率有所提升 3.脱机批处理系统 CPU效率极大提升(现代计算机雏形) 多道技术(单核CPU) 串行:多个任务依 ...
- python学习笔记-进程线程
1.什么是进程(process)? 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述 ...
- Python并发编程-进程 线程 同步锁 线程死锁和递归锁
进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...
- 守护进程,互斥锁,IPC,生产者与消费者模型
守护进程: b 进程守护 a进程,当a进程执行完毕时,b进程会跟着立马结束 守护进程用途: 如果父进程结束了,子进程无需运行了,就可以将子进程设置为父进程的守护进程 例如我们qq视频聊天时,当我们退出 ...
随机推荐
- Silverlight自定义控件系列 – TreeView (2) 基本布局和States
TreeView的树形结构都以缩进方式显示,现在来完成这部分. 首先,要定义出每个节点上都包含什么东西.先看看Win7资源管理器的TreeView: 图2.1 资源管理器 一个通用的TreeView至 ...
- English trip -- VC(情景课) 7 C How much are the shose? 鞋多少钱
Grammar focus 语法点: How much is ...? How much are...? How much is the shirt? $15.99. How much are ...
- 牛客网暑期ACM多校训练营(第三场)DEncrypted String Matching fft
题意:给你一个解密后的字符串,给你加密方式,加密过程可能出错,字符可能加减1,然后给你一个字符串,要求匹配个数(其实我也不太懂具体怎么加密解密,反正你把给你的前两个字符串用第三个加密一下,然后搞可以有 ...
- python-day4笔记
1.文件后缀名对python运行没关系 2.Python解释器执行python程序的过程:python3 C:\test.py 1)启动python解释器(内存中) 2)将C:\test.py内容从硬 ...
- 生成图片验证码(.NET)
一.生成随机字符串 方法一: public string CreateRandomCode(int codeCount) { string allChar = "0,1,2,3,4,5,6, ...
- quartz---触发job时间和结束时间
quartz:Trigger:触发job时间和结束时间 package com.imooc.demo.helloQuartz; import java.text.SimpleDateFormat; i ...
- vnc xfce tab自动补全失效的解决方法
edit~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-keyboard-shortcuts.xml find the line <proper ...
- 循环大法——一次性理清forEach/for-in/for/$each
国寿的这个项目写得我基础都忘完了 近期会把vue和基础都并行复习.学习 forEach 适用于调用数组的每个元素,并将元素传递给回调函数,但是空数组是不会执行回调函数的.forEach适用于集合中的对 ...
- WindowsLiveWriter安装步骤
WindowsLiveWriter 安装WindowsLiveWriter.exe http://www.cnblogs.com/rhxuza1993/
- WEBSERVICE-AXIS2服务端代码
下载axis2的插件 axis2-eclipse-codegen-plugin-1.7.1.zip axis2-eclipse-service-plugin-1.7.1.zip 解压后,将plugin ...