《python》join、守护进程、锁/信号量/事件、进程队列
一、multiprocess.process模块
1、join方法
阻塞主进程,等待子进程执行完毕再放开阻塞
import time
import random
from multiprocessing import Process # 单个子进程
def func(index):
time.sleep(random.randint(1, 3))
print('发送完毕') if __name__ == '__main__':
p = Process(target=func, args=(1,))
p.start()
p.join() # 阻塞 直到p进程执行完毕就结束阻塞
print('邮件已经发送完毕')
'''
发送完毕
邮件已经发送完毕
'''
# 多个子进程
def func(index):
time.sleep(random.randint(1,3))
print('第%s个邮件已经发送完毕' % index) if __name__ == '__main__':
p_lst = []
for i in range(10):
p = Process(target=func, args=(i,))
p.start()
p_lst.append(p)
for p in p_lst:
p.join() # 等待每个子进程执行完毕
print('10个邮件已经发送完毕')
'''
第2个邮件已经发送完毕
第4个邮件已经发送完毕
第7个邮件已经发送完毕
第5个邮件已经发送完毕
第1个邮件已经发送完毕
第9个邮件已经发送完毕
第0个邮件已经发送完毕
第3个邮件已经发送完毕
第8个邮件已经发送完毕
第6个邮件已经发送完毕
10个邮件已经发送完毕
'''
2、第二种开启进程的方法
以继承Process类的形式开启进程的方式
import os
from multiprocessing import Process class MyProcess(Process):
def run(self):
print('子进程: ', os.getpid(), os.getppid()) if __name__ == '__main__':
p = MyProcess()
p.start() # 开启一个子进程,让这个子进程执行run方法
print('主进程:', os.getpid())
'''
主进程: 6852
子进程: 6644 6852
''' # 给子进程传参数 class MyProcess(Process):
def __init__(self, arg):
super().__init__()
self.arg = arg
def run(self):
time.sleep(1)
print('子进程: ', os.getpid(), os.getppid(), self.arg) if __name__ == '__main__':
# 开启单个子进程
p = MyProcess('参数')
p.start() # 开启一个子进程,让这个子进程执行run方法
p.join()
print('主进程:', os.getpid())
'''
子进程: 6552 7784 参数
主进程: 7784
''' if __name__ == '__main__':
# 开启多个子进程
for i in range(10):
p = MyProcess('参数%s' % i)
p.start() # 开启一个子进程,让这个子进程执行run方法
print('主进程:', os.getpid())
'''
主进程: 7340
子进程: 6540 7340 参数0
子进程: 6512 7340 参数3
子进程: 7648 7340 参数1
子进程: 7460 7340 参数2
子进程: 8048 7340 参数4
子进程: 5108 7340 参数8
子进程: 7868 7340 参数7
子进程: 7892 7340 参数6
子进程: 4172 7340 参数9
子进程: 7224 7340 参数5
'''
3、守护进程
主要功能:每隔一段时间就向一台机器汇报自己的状态(程序的报活)
特点:会随着主进程的结束而结束。
import time
from multiprocessing import Process def func():
print('子进程 start')
time.sleep(3)
print('子进程 end') if __name__ == '__main__':
p = Process(target=func)
p.daemon = True # 设置p为一个守护进程,必须在start之前完成
p.start()
time.sleep(2)
print('主进程')
'''
子进程 start
主进程
'''
# 主进程会等待子进程完全结束才结束
# 守护进程会随着主进程的代码执行完毕而结束
def func1():
count = 1
while 1:
print(count * '*')
time.sleep(0.5)
count += 1 def func2():
print('func2 start')
time.sleep(5)
print('func2 end') if __name__ == '__main__':
p1 = Process(target=func1)
p1.daemon = True
p1.start() # p1是守护进程
p2 = Process(target=func2)
p2.start()
time.sleep(3)
print('主进程')
'''
func2 start
*
**
***
****
*****
******
主进程
func2 end
'''
# 如果主进程代码已经执行完毕,但是子进程还没执行完,守护进程都不会继续执行
# 守护进程会随着主进程的代码执行完毕而结束
# 主进程会等待子进程结束,守护进程只等待主进程代码结束就结束了
二、进程同步(multiprocess.Lock、multiprocess.Semaphore、multiprocess.Event)
1、锁---multiprocess.Lock
加锁降低了程序的效率,让原来能够同时执行的代码变成顺序执行了,异步变同步的过程
好处:保证了数据的安全
import time
import json
from multiprocessing import Process, Lock # 当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。 # 多进程抢占输出资源
def search(person):
with open('ticket') as f:
dic = json.load(f)
time.sleep(0.2) # 模拟网络延迟
print('%s查询余票:' % person, dic['count']) def get_ticket(person):
with open('ticket') as f:
dic = json.load(f)
time.sleep(0.2) # 模拟网络延迟
if dic['count'] > 0:
print('%s买到票了' % person)
dic['count'] -= 1 # 买到票,数量减1
time.sleep(0.2) # 模拟网络延迟
with open('ticket', 'w') as f:
json.dump(dic, f) # 把剩余票数写回文件
else:
print('%s没买到票' % person) def ticket(person):
search(person) # 查票
get_ticket(person) # 抢票 if __name__ == '__main__':
for i in range(10):
p = Process(target=ticket, args=('person%s' % i,))
p.start()
'''
person0查询余票: 5
person4查询余票: 5
person3查询余票: 5
person0买到票了
person8查询余票: 5
person2查询余票: 5
person7查询余票: 5
person4买到票了
person1查询余票: 5
person5查询余票: 5
person3买到票了
person9查询余票: 5
person6查询余票: 5
person8买到票了
person2买到票了
person7买到票了
person1买到票了
person9买到票了
person6买到票了
person5买到票了
''' # 使用锁维护执行顺序
def search(person):
with open('ticket') as f:
dic = json.load(f)
time.sleep(0.2) # 模拟网络延迟
print('%s查询余票:' % person, dic['count']) def get_ticket(person):
with open('ticket') as f:
dic = json.load(f)
time.sleep(0.2) # 模拟网络延迟
if dic['count'] > 0:
print('%s买到票了' % person)
dic['count'] -= 1 # 买到票,数量减1
time.sleep(0.2) # 模拟网络延迟
with open('ticket', 'w') as f:
json.dump(dic, f) # 把剩余票数写回文件
else:
print('%s没买到票' % person) def ticket(person, lock):
search(person)
lock.acquire() # 加锁
get_ticket(person)
lock.release() # 解锁 if __name__ == '__main__':
lock = Lock()
for i in range(10):
p = Process(target=ticket, args=('person%s' % i, lock))
p.start()
'''
person0查询余票: 5
person1查询余票: 5
person2查询余票: 5
person0买到票了
person5查询余票: 5
person6查询余票: 5
person3查询余票: 5
person9查询余票: 5
person4查询余票: 5
person8查询余票: 5
person7查询余票: 5
person1买到票了
person2买到票了
person5买到票了
person6买到票了
person3没买到票
person9没买到票
person4没买到票
person8没买到票
person7没买到票
'''
# 为了保证数据的安全
# 在异步的情况下,多个进程有可能同时修改同一份资源
# 就给这个修改的过程加上锁
import time
from multiprocessing import Process, Lock # 加了锁就把异步变成同步了
def func(num, lock):
time.sleep(1)
print('异步执行', num) # 异步会同时开始 lock.acquire()
time.sleep(0.5)
print('同步执行', num) # 同步要一个结束才开始下一个
lock.release() if __name__ == '__main__':
lock = Lock()
for i in range(10):
p = Process(target=func, args=(i, lock))
p.start()
from multiprocessing import Process, Lock # 互斥锁
lock = Lock()
lock.acquire()
print('')
lock.acquire()
print('')
# 只打印456,123不打印
2、信号量---multiprocess.Semaphore
信号量的实现机制:计数器 + 锁 实现的
import time
import random
from multiprocessing import Process, Semaphore def ktv(person, sem):
sem.acquire()
print('\033[32m%s走进ktv\033[0m' % person)
time.sleep(random.randint(1,5))
print('\033[31m%s走出ktv\033[0m' % person)
sem.release() if __name__ == '__main__':
sem = Semaphore(4) # 限定4个
for i in range(10):
p = Process(target=ktv, args=('person%s' % i, sem))
p.start()
'''
person2走进ktv
person1走进ktv
person3走进ktv
person0走进ktv
person1走出ktv
person6走进ktv
person6走出ktv
person7走进ktv
person2走出ktv
person5走进ktv
person3走出ktv
person9走进ktv
person0走出ktv
person8走进ktv
person7走出ktv
person4走进ktv
person8走出ktv
person9走出ktv
person5走出ktv
person4走出ktv
'''
3、事件---multiprocess.Event
阻塞事件:wait()方法
wait 是否阻塞是看 event 对象内部的一个属性
控制这个属性的值
set() 将这个属性的值改成True
clear() 将这个属性的值改成False
is_set() 判断当前的属性是否为True
import time
import random
from multiprocessing import Process, Event def traffic_light(e):
print('\033[31m红灯亮\033[0m')
while 1:
if e.is_set():
time.sleep(2)
print('\033[31m红灯亮\033[0m')
e.clear()
else:
time.sleep(2)
print('\033[32m绿灯亮\033[0m')
e.set() def car(e, i):
if not e.is_set():
print('car %s 在等待' % i)
e.wait()
print('car %s 通过了' % i) if __name__ == '__main__':
e = Event()
p = Process(target=traffic_light, args=(e,))
p.daemon = True
p.start()
p_lst = []
for i in range(20):
time.sleep(random.randrange(0, 3, 2))
p = Process(target=car, args=(e, i))
p.start()
p_lst.append(p)
for p in p_lst:
p.join()
'''
红灯亮
car 0 在等待
car 1 在等待
绿灯亮
car 1 通过了
car 0 通过了
car 2 通过了
car 3 通过了
car 4 通过了
红灯亮
car 7 在等待
car 6 在等待
car 5 在等待
car 8 在等待
绿灯亮
car 6 通过了
car 7 通过了
car 8 通过了
car 5 通过了
红灯亮
car 9 在等待
绿灯亮
car 9 通过了
car 11 通过了
car 10 通过了
红灯亮
car 12 在等待
car 13 在等待
绿灯亮
car 13 通过了
car 12 通过了
car 15 通过了
car 14 通过了
红灯亮
car 17 在等待
car 16 在等待
car 18 在等待
绿灯亮
car 16 通过了
car 17 通过了
car 18 通过了
car 19 通过了
'''
《python》join、守护进程、锁/信号量/事件、进程队列的更多相关文章
- python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))
昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...
- 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)
参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...
- Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures
参考博客: https://www.cnblogs.com/xiao987334176/p/9046028.html 线程简述 什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线 ...
- python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)
昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...
- python 并发编程 锁 / 信号量 / 事件 / 队列(进程间通信(IPC)) /生产者消费者模式
(1)锁:进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 虽然使用加锁的形式实现了 ...
- python 锁 信号量 事件 队列
什么是python 进程锁? #同步效率低,但是保证了数据安全 重点 很多时候,我们需要在多个进程中同时写一个文件,如果不加锁机制,就会导致写文件错乱 这个时候,我们可以使用multiprocess ...
- python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)
#######################总结######### 主要理解 锁 生产者消费者模型 解耦用的 队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...
- python 多线程、线程锁、事件
1. 多线程的基本使用 import threading import time def run(num): print('Num: %s'% num) time.sleep(3) if num == ...
- Python--day38--进程同步控制的---锁\信号量\事件的方法名
随机推荐
- 最多的划分来使数组有序 Max Chunks To Make Sorted
2018-12-01 11:05:46 一.Max Chunks To Make Sorted 问题描述: 问题求解: 由于没有重复,所以直观的来看对于每个遇到数,其能够被划分出来的前提是其前面已经有 ...
- windows安装使用docker
doker就是一个容器,如果想要在windows安装还必须要用另外一个工具docker-toolbox.下载地址:https://mirrors.aliyun.com/docker-toolbox/w ...
- HAL无阻塞延时
//实现间隔time_interval时间点亮红灯(此时间间隔并不是绝对的,是大于等于的关系)//用于系统要求无延时且延时时间粗略的场合,比如间隔一段时间采样数据,间隔一段时间点亮状态灯等//HAL_ ...
- HTML第四章总结
Move to the Webville!!! 总述 这一章分为两个部分: 如何发布自己的 HTML 文件到 Web 上. 如何在网站上更好地利用 Hypertext. 第一部分:如何发布自己的 HT ...
- linux ----> centos 网络、tomcat、vi、等等的配置和使用
网络/配置 环境: centos6.8-mini-version virtualbox 工具: FileZilla client SecureCRT 静态ip地址 每一台计算机分配有一个固定的IP地 ...
- LeetCode--013--罗马数字转整数(java)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并 ...
- LeetCode--283--移动0
问题描述: 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原 ...
- python基础之函数名的使用,闭包以及迭代器
内容梗概: 1. 函数名的使⽤用以及第⼀一类对象 2. 闭包 3. 迭代器 1.函数名一. 函数名的运⽤.函数名是一个变量, 但它是⼀个特殊的变量, 与括号配合可以执行函数的变量.1.1 函数名的内存 ...
- Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined)G. Sum the Fibonacci
题意:给一个数组s,求\(f(s_a | s_b) * f(s_c) * f(s_d \oplus s_e)\),f是斐波那契数列,而且要满足\(s_a\&s_b==0\),\((s_a | ...
- CentOS虚拟机和物理机共享文件夹实现
安装open-vm-tools: yum -y install open-vm-tools yum -y install open-vm-tools yum -y install open-vm ...