1.守护进程

什么是守护进程?

  进程是一个正在运行的程序

  守护进程也是一个普通进程,意思是一个进程可以守护另一个进程,比如如果b是a的守护进程,a是被守护的进程,如果a进程结束,b进程也会随之结束。

使用场景:

  父进程交给了子进程一个任务,子进程在执行过程中并没有执行完毕,但是父进程结束了,那么子进程就没又继续执行的意义了

使用方法:在start 前面加 deamon = Ture

案例:

from multiprocessing import Process
import time
def task():
print('子进程开启了')
time.sleep(5)
print('你跟着去吧') if __name__ == '__main__':
print('父进程开始了')
p = Process(target=task) # 使用daemon方法来守护父进程,如果父进程提前结束了
# 那么子进程也会一起结束
p.daemon = True
p.start()
time.sleep(2)
print('父进程结束了')

2.互斥锁

什么是互斥锁?

  互斥锁,意思是互相排斥的锁,在程序中的意思是。如果这个资源已经被锁定了,那么其他的进程则无法使用该资源

PS: 锁,并不是真的把资源锁起来了,只是在代码层面限制你的代码不能执行

为什么需要互斥锁?

  并发带来资源的竞争问题:

当多个进程同时要操作同一个资源时,将会导致数据错乱的问题,那么解决这样问题的方案有两种

  1. 是用 join ,等子进程结束后再执行其他进程,这样做的效果确实能实现资源竞争的问题,但是却降低了效率,如果这样操作就没有必要开启子进程了,而且本来多个进程之间是公平竞争的,而join方法,就必须按照join的执行顺序来进行,所以这是不合理的

  2. 给公共资源加锁  

  每个进程间是公平的,都是同时竞争,但是如果有一个进程抢到了资源,就会把资源锁住,那么其他的程序就只能等哪个进程释放锁之后才能使用。

锁与join的区别

  1. join是固定了执行顺序,不仅会造成父进程等待子进程结束后才能继续执行,而且浪费资源

  而锁是公平竞争,谁先抢到谁先执行,父进程依然可以继续执行,不受干扰

  2.最主要i的区别

  join是把进程的任务全部串行

  锁可以锁任意代码,可以自主的调整锁定的粒度

使用方法:

  在你需要执行的代码前加 acpuire 方法,代码的后面加 release

案例:

'''
并发将带来资源的竞争问题
当多个进程同时要操作同一个资源时,将会导致数据错乱的问题 ''' def task1(lock):
# acquire 将进程上锁(并不是上锁),是让其他进程必须等抢到系统资源
# 的进程执行完毕后才能执行
lock.acquire()
print('哒哒哒哒哒哒冒蓝光的加特林')
print('biubiubiubiu冒红光的M416')
print('砰砰砰砰砰砰冒黄光的手榴弹')
# 当进程执行完后要释放锁,让其他进程使用
lock.release() def task2(lock):
lock.acquire()
print('冒蓝光的加特林')
print('冒红光的M416')
print('黄光的手榴弹')
lock.release() def task3(lock):
lock.acquire()
print('加特林')
print('M416')
print('手榴弹')
lock.release() if __name__ == '__main__':
# 需要先实例化得到一把锁
# 需要注意的是,不要对同一把执行两次acquire,会锁死
# 导致程序无法运行,一此acquire必须对应一次release
lock = Lock()
p1 = Process(target=task1, args=(lock,))
p2 = Process(target=task2, args=(lock,))
p3 = Process(target=task3, args=(lock,)) p1.start()
p2.start()
p3.start()

3.IPC

IPC = 进程间通讯 (通讯指的是互相交换数据)

进程之间内存是相互隔离的,当一个进程想要把数据给另外一个进程的时候,就需要考虑IPC

进程之间传输数据的方式:

  1.管道:只能单向通讯,数据都是二进制(subprocess)

  2.文件:在银盘上创建共享文件

    缺点: 速度慢

       优点: 数据量没有限制

  3.socket

    编程难度复杂

  4. 共享内存

    优点: 速度块

    缺点: 数据量不能太大

共享内存的方式

Manager类

  Manager提供很多数据结构 list dict 等等

  Manager所创建出来的数据结构,具备进程间共享的特点

案例:

from multiprocessing import Process,Manager,Lock
def task(data, lock):
lock.acquire()
num = data['num'] data['num'] = num - 1
lock.release() if __name__ == '__main__':
# Manager 开启一个共享字典,这个字典子进程与父进程公同拥有
m = Manager()
data = m.dict({'num': 10})
lock = Lock() for i in range(10):
p = Process(target=task, args=(data, lock))
p.start()
p.join()
print(data)

PS: 需要强调的是Manager创建的一些数据结构是不带锁的,可能会出现问题

4.Queue队列  *****(重点)

Queue队列帮我们处理了锁的问题,重点

  队列是一种特殊的数据结构,先存储的先取出,先进先出

  相反的是堆区,先存储的后取出,先进后出

PS:函数嵌套调用时,执行顺序是先进后出的,所以也称之为函数栈

  调用函数时,函数入栈,函数结束就出栈

案例:

from multiprocessing import Queue

# 创建队列,不指定maxsize 则没有数量限制
q = Queue(3) # 存储元素
q.put('abc')
q.put('')
q.put('哈哈哈') print(q.get())
print(q.get())
print(q.get()) # 如果容量已经满了,在调用put时将会进入阻塞状态
# 直到有人从队列中拿走数据有空位置才会继续执行 # 如果队列已经空了,在调用get时将进入阻塞状态,
# 直到有人存储了新的数据到队列中,才会继续 # block 表示是否需要进行阻塞,默认是阻塞的,当设置为False,并且队列为空时,则抛出异常
# timeout 表示阻塞的超时时间,超过时间还是没有值或还是没位置则抛出异常,仅在block为True有效 # 此处如果没有值,则会阻塞两秒,如果还没有值,则报异常
# q.get(block=True,timeout=2) # 此处存值时,如果容器满了,则不会阻塞,直接报异常
# q.put('123', block=False)

5.生产消费着模型

生产者:产生数据的一方

消费者:处理数据的一方

生产者与消费者中存在的问题:

生产者和消费者处理速度不平衡,一方快一方慢,导致一方需要等待另一方

双方是耦合在一起的,消费者必须等待生产者生成完毕后才能开始处理,

但是如果消费者消费速度太慢,生产者必须等待其处理完毕才能开始生成下一个数据

解决途径:

  将双方分开,生产者专门生产,消费者专门消费,两者不需要等待某一方结束后才能执行

但是这样一来就需要一个共同的容器,生产者完成后放入容器,消费者从容器中取出数据,这样就解决了双方能力不平衡的问题,完成时间快的一方继续完成,无需等待另一方

案例:

from multiprocessing import Process, Queue, Lock
import time, random, os # 消费者
def consumer(q):
# 假如消费者点了10盘菜
for i in range(10):
# 因为吃饭需要时间,所以使用tiem模拟了时间
time.sleep(random.randint(0, 2))
# 通过从Queue容器获取生产者的数据
rose = q.get()
print('%s已经吃完了%s' % (os.getpid(), rose)) # 生产者
def producer(q):
# 生产者需要烧制10盘菜
for i in range(10):
# 因为制作菜需要时间,所以也使用了tiem 模拟了时间
time.sleep(random.randint(0, 2))
print('第%s盘菜烧好了' % i)
rose = ('第%s盘菜' % i)
# 使用put方法往Queue中添加数据
q.put(rose) if __name__ == '__main__':
# 创造一个Queue来存储数据
q = Queue()
c = Process(target=consumer,args=(q,))
p = Process(target=producer,args=(q,))
c.start()
p.start()

守护进程,互斥锁, IPC ,Queue队列,生产消费着模型的更多相关文章

  1. 进程(守护进程--互斥锁--IPC机制--生产者模型--僵尸进程与孤儿进程--模拟抢票--消息队列)

    目录 一:进程理论知识 1.理论知识 二:什么是进程? 三:僵尸进程与孤儿进程 1.僵尸进程 四:守护进程 1.什么是守护进程? 2.主进程创建守护进程 3.守护进程 五:互斥锁(模拟多人抢票) 1. ...

  2. 守护进程,互斥锁,IPC,队列,生产者与消费者模型

    小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某 ...

  3. 守护模式,互斥锁,IPC通讯,生产者消费者模型

    '''1,什么是生产者消费者模型 生产者:比喻的是程序中负责产生数据的任务 消费者:比喻的是程序中负责处理数据的任务 生产者->共享的介质(队列)<-消费者 2,为何用 实现了生产者与消费 ...

  4. 4-[多进程]-互斥锁、Queue队列、生产者消费者

    1.互斥锁 (1)为什么需要互斥锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如下 #并发运行,效率 ...

  5. 进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型

    一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: import param ...

  6. 4 并发编程-(进程)-守护进程&互斥锁

    一.守护进程 主进程创建子进程,然后将该进程设置成守护自己的进程,守护进程就好比崇祯皇帝身边的老太监,崇祯皇帝已死老太监就跟着殉葬了. 关于守护进程需要强调两点: 其一:守护进程会在主进程代码执行结束 ...

  7. 8.9 day30 并发编程 进程理论 进程方法 守护进程 互斥锁

    多道技术 1.空间上的复用 多个程序共用一套计算机硬件 多道技术原理 2.时间上的复用 ​ 切换+保存状态 ​ 1.当一个程序遇到IO操作 操作系统会剥夺该程序的CPU执行权限( 提高了CPU的利用率 ...

  8. python并发编程-进程理论-进程方法-守护进程-互斥锁-01

    操作系统发展史(主要的几个阶段) 初始系统 1946年第一台计算机诞生,采用手工操作的方式(用穿孔卡片操作) 同一个房间同一时刻只能运行一个程序,效率极低(操作一两个小时,CPU一两秒可能就运算完了) ...

  9. 4、网络并发编程--僵尸进程、孤儿进程、守护进程、互斥锁、消息队列、IPC机制、生产者消费者模型、线程理论与实操

    昨日内容回顾 操作系统发展史 1.穿孔卡片 CPU利用率极低 2.联机批处理系统 CPU效率有所提升 3.脱机批处理系统 CPU效率极大提升(现代计算机雏形) 多道技术(单核CPU) 串行:多个任务依 ...

随机推荐

  1. Java 对象序列化和反序列化 (实现 Serializable 接口)

    序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化.  把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放 ...

  2. 编译gpu集群版caffe

    在这个版本安装之前,要先装好opencv,openmpi等. 下载地址:https://github.com/yjxiong/caffe.git 我的opencv是2.4.12版本 编译是用了: cm ...

  3. 高并发下的 Nginx 优化与负载均衡

    高并发下的 Nginx 优化   英文原文:Optimizing Nginx for High Traffic Loads 过去谈过一些关于Nginx的常见问题; 其中有一些是关于如何优化Nginx. ...

  4. Oracle之:Function :getcurrdate()

    getdate()函数连接请戳这里 create or replace function getcurrdate(i_date date) return date is v_date date; v_ ...

  5. 常用NoSql数据库比较

    1. CouchDB 所用语言: Erlang 特点:DB一致性,易于使用 使用许可: Apache 协议: HTTP/REST 双向数据复制, 持续进行或临时处理, 处理时带冲突检查, 因此,采用的 ...

  6. 【环境配置】出现:Microsoft Visual C++ 14.0 is required 的解决方案

    参考blog https://download.csdn.net/download/amoscn/10399046 https://blog.csdn.net/weixin_42057852/arti ...

  7. MFC CTreeCtrl 递归遍历算法

    递归遍历 void Traverse(HTREEITEM hTree) { if (!hTree) { return; } //Do Something. //Traverse Child Node ...

  8. CDOJ 1256 打表+数组 统计

    昊昊爱运动 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  St ...

  9. 灰度图像--图像分割 霍夫变换(Hough Transform)--直线

    学习DIP第50天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan ,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发:https://gi ...

  10. Spring——MyBatis整合

    一.xml配置版 1.导入依赖 <!--MyBatis和Spring的整合包 由MyBatis提供--> <dependency> <groupId>org.myb ...