day35 守护进程、互斥锁、IPC
day35 守护进程、互斥锁、IPC
1、守护进程
# 守护进程:当父进程执行完毕后,设置的守护进程也会跟着结束
# 当一个进程被设置为守护进程后,其不能再产生子进程
from multiprocessing import Process
import time
def test():
print("妃子入宫了")
time.sleep(5)
print("子进程挂了")
if __name__ == '__main__':
p = Process(target=test)
p.daemon = True
p.start()
time.sleep(3)
print("父进程挂了") # 妃子入宫了
# 父进程挂了
2、互斥锁
# 在进行打印操作时,如果三个全部进行打印操作就会互相影响打印结果
# 所以此时需要将打印操作设置为串行
#使用join方法可以将优先级进行提升,但是这样执行顺序就固定了,就不能使每个子进程公平竞争CPU
# 如果按照下方的程序进行处理,那么这样就没有开启子进程的意义了
def test():
print("i am li")
time.sleep(random.random())
print("my age is 15")
time.sleep(random.random())
print("i am a boy")
def test2():
print("i am lee")
time.sleep(random.random())
print("my age is 20")
time.sleep(random.random())
print("i am a girl")
def test3():
print("i am wu")
time.sleep(random.random())
print("my age is 25")
time.sleep(random.random())
print("i am a man")
if __name__ == '__main__':
p = multiprocessing.Process(target=test)
p1 = multiprocessing.Process(target=test3)
p2 = multiprocessing.Process(target=test2)
p.start()
p.join()
p1.start()
p1.join()
p2.start()
p2.join() # i am li
# my age is 15
# i am a boy
# i am lee
# my age is 20
# i am a girl
# i am wu
# my age is 25
# i am a man
# 使用互斥锁
# lock = Lock()
# 注意:互斥锁不能在全部变量中进行设置,这是因为子进程在进行设置时,会导入父进程的代码,
# 只有放在if __name__ == "__main__"中确保使用的是同一把锁
# 使用join与互斥锁的区别:
# 1、join会人为的打乱子进程的优先级,从而使某个子进程首先执行完,打乱了公平竞争
# 2、join只能将整个函数的优先级进行提高,不能对其中的某一行进行操作
# 互斥锁可以直接对函数中的某一行代码进行操作,这样在进行程序的执行时,可以提高程序的执行效率
# 这种又称之为粒度,粒度越小,执行效率越高,粒度越大执行效率越低
# 实际上,互斥锁不是锁住的文件或者共享资源,
# 而是在共享内存中增加一个标志,当碰到Lock对象时就会去全局变量中访问这个标志,如果这个标志为True就会执行acquire方法,将共享空间中的标志改为False
# 如果标志为False就不能执行这段代码,直到等到更改这个变量的对象再次访问全局变量,并使用release方法将这个标志重新改为True,其余进程才能访问并更改这个标志
def test(lock):
lock.acquire()
print("i am li")
time.sleep(random.random())
print("my age is 15")
time.sleep(random.random())
print("i am a boy")
lock.release()
def test2(lock):
lock.acquire()
print("i am lee")
time.sleep(random.random())
print("my age is 20")
time.sleep(random.random())
print("i am a girl")
lock.release()
def test3(lock):
lock.acquire()
print("i am wu")
time.sleep(random.random())
print("my age is 25")
time.sleep(random.random())
print("i am a man")
lock.release()
if __name__ == '__main__':
lock = Lock()
p = multiprocessing.Process(target=test,args=(lock,))
p1 = multiprocessing.Process(target=test3,args=(lock,))
p2 = multiprocessing.Process(target=test2,args=(lock,))
p.start()
p1.start()
p2.start() # i am li
# my age is 15
# i am a boy
# i am wu
# my age is 25
# i am a man
# i am lee
# my age is 20
# i am a girl
3、互斥锁的应用
import multiprocessing
from multiprocessing import Lock
import time
import json
import random
def show_ticket(i):
time.sleep(random.random())
with open("aa.json","rt",encoding="utf-8") as f:
num_dic = json.load(f)
time.sleep(random.random())
print("%s正在查看余票,余票数量为%s"%(i,num_dic["num"]))
return num_dic["num"]
def buy_ticket(i):
time.sleep(random.random())
with open("aa.json","rt",encoding="utf-8") as f:
num_dic = json.load(f)
ticket_num = num_dic["num"]
if ticket_num > 0:
time.sleep(random.random())
ticket_num -= 1
num_dic["num"] = ticket_num
print("%s抢票成功"%i)
with open("aa.json","wt",encoding="utf-8") as f:
print(num_dic)
json.dump(num_dic,f)
else:
print("%s余票数量为%s,抢票失败"%(i,ticket_num))
def run(i,lock):
show_ticket(i)
lock.acquire()
buy_ticket(i)
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(10):
p = multiprocessing.Process(target=run,args=[i,lock])
p.start()
# 执行结果为: # 1正在查看余票,余票数量为1
# 0正在查看余票,余票数量为1
# 4正在查看余票,余票数量为1
# 3正在查看余票,余票数量为1
# 6正在查看余票,余票数量为1
# 5正在查看余票,余票数量为1
# 8正在查看余票,余票数量为1
# 2正在查看余票,余票数量为1
# 7正在查看余票,余票数量为1
# 1抢票成功
# {'num': 0}
# 0余票数量为0,抢票失败
# 9正在查看余票,余票数量为1
# 4余票数量为0,抢票失败
# 3余票数量为0,抢票失败
# 6余票数量为0,抢票失败
# 5余票数量为0,抢票失败
# 8余票数量为0,抢票失败
# 2余票数量为0,抢票失败
# 7余票数量为0,抢票失败
# 9余票数量为0,抢票失败
4、IPC
# IPC (inter-process communication):进程间通信
# 在内存中,进程间的内存是相互独立的,如果想要使用其他进程中的数据此时需要进程间的通信
# 实现进程间通信的方式:
# 1、使用共享文件
# 2、使用共享内存
# 3、使用管道
# 4、使用队列
# 使用共享文件进行进程间通信:由于文件存在于硬盘中,使用该方法进行通信效率较低,较耗时
# 使用subprocess管道进行进程间通信:管道只能进行单向的进程通信
# 使用共享内存进行进程间通信
# 使用共享内存的方法进行进程间通信,由于进程访问的是同一个数据,所以需要加互斥锁,如果不加将会影响数据的安全性
# 在父进程中设置共享内存的内容,如果父进程在子进程还执行时结束,那么就会报错,此时必须设置join方法使父进程在子进程结束后再结束
# 由于使用互斥锁存在死锁的问题,所有尽量少使用这种方式实现进程间通信
from multiprocessing import Manager,Lock
import multiprocessing
import time
import random
def fn(dic,lock):
time.sleep(random.random())
# lock.acquire()
a = dic["a"]
a = a-1
time.sleep(random.random())
dic["a"] = a
# lock.release()
print(dic["a"])
if __name__ == '__main__':
dic = {"a":10}
lock = Lock()
manage = Manager()
data = manage.dict({"a":10})
for i in range(10):
p = multiprocessing.Process(target=fn,args=[data,lock])
p.start()
time.sleep(8)
print(data["a"])
# 使用队列(Queue)实现进程间通信
# 在multiprocessing 中封装了Queue类来通过队列实现进程间的通讯
from multiprocessing import Queue
q = Queue(4)
q.put(1)
q.put(2)
q.put(3)
q.put(4)
q.put(5) # 当在队列创建时设置了队列的最大值,那么当队列中存在的值超过队列的最大值时就会处于阻塞状态,直到队列中的值被取出后剩下的数量少于设置的最大值
print(q.get())
print(q.get())
print(q.get())
print(q.get()) # 当管道中的数据被取出后,进程就会处于阻塞态,等待着队列中添加数据
# q.get及q.put中的其它参数
# 1、block(阻塞):默认为True,如果设置为False,那么在超出队列最大值,或者队列中的值被取完后还在取值时报错
# 2、timeout : 只有在block 设置为True时才有效,当设置该值后,在进入阻塞态一段时间后才会报错
5、生产者消费者模型
# 生产者消费者模型
import time
from multiprocessing import Queue,Process
import random
def maker(q):
for i in range(10):
time.sleep(random.random())
print("第%s份食物做好啦..."%i)
q.put(i)
def eater(q):
for t in range(10):
i = q.get()
time.sleep(random.random())
print(" 第%s份食物吃完啦..."%i)
# 在不使用多进程之前,相当于只有一份餐具,我们只能创建一份吃一份食物
# for i in range(10):
# maker(i)
# eater(i)
# 在多进程中,创建食物与吃食物可以一起进行,相当于有好多餐具
if __name__ == '__main__':
q = Queue()
mp = Process(target=maker,args=[q,])
ep = Process(target=eater,args=[q,])
mp.start()
ep.start()
day35 守护进程、互斥锁、IPC的更多相关文章
- 守护进程,互斥锁,IPC,队列,生产者与消费者模型
小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某 ...
- 进程(守护进程--互斥锁--IPC机制--生产者模型--僵尸进程与孤儿进程--模拟抢票--消息队列)
目录 一:进程理论知识 1.理论知识 二:什么是进程? 三:僵尸进程与孤儿进程 1.僵尸进程 四:守护进程 1.什么是守护进程? 2.主进程创建守护进程 3.守护进程 五:互斥锁(模拟多人抢票) 1. ...
- 守护模式,互斥锁,IPC通讯,生产者消费者模型
'''1,什么是生产者消费者模型 生产者:比喻的是程序中负责产生数据的任务 消费者:比喻的是程序中负责处理数据的任务 生产者->共享的介质(队列)<-消费者 2,为何用 实现了生产者与消费 ...
- 4 并发编程-(进程)-守护进程&互斥锁
一.守护进程 主进程创建子进程,然后将该进程设置成守护自己的进程,守护进程就好比崇祯皇帝身边的老太监,崇祯皇帝已死老太监就跟着殉葬了. 关于守护进程需要强调两点: 其一:守护进程会在主进程代码执行结束 ...
- 8.9 day30 并发编程 进程理论 进程方法 守护进程 互斥锁
多道技术 1.空间上的复用 多个程序共用一套计算机硬件 多道技术原理 2.时间上的复用 切换+保存状态 1.当一个程序遇到IO操作 操作系统会剥夺该程序的CPU执行权限( 提高了CPU的利用率 ...
- python并发编程-进程理论-进程方法-守护进程-互斥锁-01
操作系统发展史(主要的几个阶段) 初始系统 1946年第一台计算机诞生,采用手工操作的方式(用穿孔卡片操作) 同一个房间同一时刻只能运行一个程序,效率极低(操作一两个小时,CPU一两秒可能就运算完了) ...
- 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发
子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...
- (day29) 进程互斥锁 + 线程
目录 进程互斥锁 队列和堆栈 进程间通信(IPC) 生产者和消费者模型 线程 什么是线程 为什么使用线程 怎么开启线程 线程对象的属性 线程互斥锁 进程互斥锁 进程间数据不共享,但是共享同一套文件系统 ...
- Java使用FileLock实现Java进程互斥锁
原理:JDK的nio包中FileLock实现类似Linux fcntl的文件锁, 可使文件被进程互斥访问. 借助此功能, 可以实现强大的Java进程互斥锁, 从而在应用层面保证同一时间只有惟一的Ja ...
随机推荐
- Connect AS400 through firewall(JDBC will require ports: 449, 8470, 8471, and 8476)
What TCP ports are used by ODBC to connect to the DB2/400? 8471/9471 http://search400.techtarget.co ...
- which/whereis
which 查找二进制命令,按环境变量PATH路径查找 whereis 查找二进制命令,按环境变量PATH路径查找 查询命令的安装路径,配置文件路径
- 51 Nod 1572 宝岛地图
1572 宝岛地图 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 勇敢的水手们到达了一个小岛,在这个小岛上,曾 ...
- 【luoguP1196】 [NOI2002]银河英雄传说--边带权并查集 ,
题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...
- Java中properties可以读取,但是里面的数据读取不到
今天配置一个项目jdbc.properties这个文件里面的键值总是读取不到,刚开始以为是文件没有读取到,但是测试是读取到的,再排查键值是不是写错了, 后来发现键值是对的,这就很奇怪了 比较是没有任何 ...
- sass,compass学习笔记总结
最近在进行百度前端技术学院的任务,知道自己基础薄弱,可没想到弱到这种地步,同时在安装各种软件的同时遇到了各种坑,查阅了各种资料,一个个解决的时候也发现自己凌乱了.学习总结,在脑海中形成自己的学习系统才 ...
- mounted里面this.$refs.xxx的内容是undefined
在mounted(){}钩子里面使用this.$refs.xxx,打印出来的却是undefined? DOM结构已经渲染出来了,但是如果在DOM结构中的某个DOM节点使用了v-if.v-show或者v ...
- java中判断空字符串和null的判断方法
简单总结几个方法: 1.直观的: if(s == null ||"".equals(s)); //先判断是否对象,再判断是否是空字符串 2.比较字符串长度, 效率高, 比较绕: i ...
- python位运算版的算术四则运算
#!/usr/bin/python # -*- coding: utf-8 -*- class ElementOperator: def add(self, num1, num2): # 32bits ...
- Leetcode题目121.买卖股票的最佳时机(简单)
题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出 ...