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

守护进程:

b 进程守护 a进程,当a进程执行完毕时,b进程会跟着立马结束

守护进程用途:

如果父进程结束了,子进程无需运行了,就可以将子进程设置为父进程的守护进程

例如我们qq视频聊天时,当我们退出qq时,视频界面会跟着退出,视频就是qq的守护进程

守护进程语法:

p.daemon = True

#1.未设置守护进程
from multiprocessing import Process
import time
def task():
    print("子进程run")
    time.sleep(2)
    print("子进程over")
if __name__ == ‘__main__‘:
    print("主进程run")
    p = Process(target = task)
    p.start()
    print("主进程over")
#执行结果
# 主进程run
# 主进程over
# 子进程run
# 子进程over
#2.设置守护进程
from multiprocessing import Process
import time
def task():
    print("子进程run")
    time.sleep(2)
    print("子进程over")
if __name__ == ‘__main__‘:
    print("主进程run")
    p = Process(target = task)
    p.daemon = True
    p.start()
    time.sleep(0.5)#让子进程起来
    print("主进程over")
#执行结果:
#主进程run
# 子进程run
# 主进程over

#3.坑
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-------")
#打印完print  main主进程就算结束了,作为守护进程的p1就挂了不会执行,而p2会执行完毕,主程序终止
#主程序的执行完毕和终止是两个概念,执行完毕是主进程的代码执行完,主进程终止 py文件停止运行
#执行结果
#main-------
#3456
#end456

强调:

设置守护进程需在子进程对象启动之前,即顺序如下:

p.daemon = True

p.start()

否则报错

Traceback (most recent call last):

# File "D:/作业/12.28/test.py", line 13, in

AssertionError: process has already started

互斥锁:

多个进程共享一份数据时,可能会造成数据错乱

此时我们需要加锁处理

from multiprocessing import Process
import time
import random
def task1():
    print("name1:wxx")
    time.sleep(random.random())
    print("age1:20")
    time.sleep(random.random())
    print("sex1:sm")
def task2():
    print("name2:egon")
    time.sleep(random.random())
    print("age2:19")
    time.sleep(random.random())
    print("sex2:fm")
def task3():
    print("name3:zb")
    time.sleep(random.random())
    print("age3:18")
    time.sleep(random.random())
    print("sex3:m")
if __name__ == ‘__main__‘:
    p1 = Process(target=task1)
    p2 = Process(target=task2)
    p3 = Process(target=task3)
    p1.start()
    p2.start()
    p3.start()
#执行结果
name1:wxx
# name2:egon
# name3:zb
# age2:19
# sex2:fm
# age3:18
# age1:20
# sex3:m
# sex1:sm

#如上模拟三个打印任务共享一台打印机,打印出的结果是乱的,不是我们想要的结果,此时cpu的利用率是高的

#解决办法:
#1.join改并发为串行,保证了数据不会乱,但执行顺序人为规定,丧失了公平性
from multiprocessing import Process
import time
import random
def task1():
    print("name1:wxx")
    time.sleep(random.random())
    print("age1:20")
    time.sleep(random.random())
    print("sex1:sm")
def task2():
    print("name2:egon")
    time.sleep(random.random())
    print("age2:19")
    time.sleep(random.random())
    print("sex2:fm")
def task3():
    print("name3:zb")
    time.sleep(random.random())
    print("age3:18")
    time.sleep(random.random())
    print("sex3:m")
if __name__ == ‘__main__‘:
    p1 = Process(target=task1)
    p2 = Process(target=task2)
    p3 = Process(target=task3)
    p1.start()
    p1.join()
    p2.start()
    p2.join()
    p3.start()
#执行结果
#name1:wxx
# age1:20
# sex1:sm
# name2:egon
# age2:19
# sex2:fm
# name3:zb
# age3:18
# sex3:m

#2加入互斥锁:
from multiprocessing import Process,Lock
import time
import random
def task1(lock):
    lock.acquire()
    print("name1:wxx")
    time.sleep(random.random())
    print("age1:20")
    time.sleep(random.random())
    print("sex1:sm")
    lock.release()
def task2(lock):
    lock.acquire()
    print("name2:egon")
    time.sleep(random.random())
    print("age2:19")
    time.sleep(random.random())
    print("sex2:fm")
    lock.release()
def task3(lock):
    lock.acquire()
    print("name3:zb")
    time.sleep(random.random())
    print("age3:18")
    time.sleep(random.random())
    print("sex3:m")
    lock.release()
if __name__ == ‘__main__‘:
    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()
#保证了数据不乱,而且随机执行,公平

互斥锁:当多个进程共享一份数据,对数据进行修改时,可能会导致数据错乱,加入互斥锁后,进程间抢锁,抢到锁的进程执行自己的代码,期间由于锁被抢走了,没有锁给剩下的进程抢,剩下的进程处于阻塞状态,当抢到锁的进程执行完自己的所有代码,释放出锁,剩下的进程又开始抢,直到最后一个进程抢到锁执行完毕自己的代码

用途:当多个进程共享一份数据并要操作数据时,保证了数据的安全性,不会错乱

强调:1.window系统,子进程的内存空间和父进程的内存空间完全独立,互不影响,此时多个子进程应该抢同一个锁,所以我们在if name == “main”中,新建一个锁,然后把锁传给各个子进程,保证了子进程抢的是同一把锁

2.抢到锁后,执行完代码,一定要记得释放锁

3.使用lock时,只可require一次,不可连续require

RLock可重入锁

首先是互斥锁

锁几次要开几次

死锁:

死锁的前提是有多把锁

程序遇到锁请求就会卡主,等释放

正常开发时,一把锁足够使用,不要开多把锁

IPC inter process communication 进程间通信

1.共享数据

2.在内存里

3.帮我们自动加锁

1.通过文件

可以传输大文件,IO时间长,从硬盘读数据慢

2.管道:基于内存,速度快,单向通讯,使用麻烦

3.队列,申请共享内存空间

传输数据不能太大,速度快,

不只用于进程间通讯,也是一种常见的数据容器

特点是:先进先出

对比堆栈刚好相反:后进先出

队列语法

```python

Queue

q = Queue(1)

q.put()放入任何类型都可以

当放满时会阻塞,

q.put(data,block = True, timeout = None)

三个参数,数据,是否阻塞,超时时间

当放满时,设置不阻塞时,会报错

q.get()

q.get(block = True,timeout = None)

是否阻塞,超时时间

当取完时,设置不阻塞时,会报错

生产者消费者模型:

1.生产者不停生产

2.消费者不停消费

3.生产者消费者之间以队列进行数据沟通

生产者消费者模型

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

原文地址:https://www.cnblogs.com/robert-zhou/p/10197951.html

时间: 2024-11-10 11:38:44

守护进程,互斥锁,IPC,生产者与消费者模型的相关文章

开启子进程的两种方式,孤儿进程与僵尸进程,守护进程,互斥锁,IPC机制,生产者与消费者模型

开启子进程的两种方式 # # # 方式一: # from multiprocessing import Process # import time # # def task(x): # print('%s is running' %x) # time.sleep(3) # print('%s is done' %x) # # if __name__ == '__main__': # # Process(target=task,kwargs={'x':'子进程'}) # p=Process(tar

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

小知识点:在子进程中不能使用input输入! 一.守护进程 守护进程表示一个进程b 守护另一个进程a 当被守护的进程结束后,那么守护进程b也跟着结束了 应用场景:之所以开子进程,是为了帮助主进程完成某个任务,然而,如果主进程认为自己的事情一旦做完了就没有必要使用子进程了,就可以将子进程设置为守护进程 例如:在运行qq的过程,开启一个进程,用于下载文件,然而文件还没有下载完毕,qq就退出了,下载任务也应该跟随qq的退出而结束. from multiprocessing import Process

35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型

守护进程 进程:一个正在运行的程序. 主进程创建守护进程: 1.守护进程会在主进程代码执行结束后就终止, 2.守护进程内无法再开启子进程,否则抛出异常. 注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止. 例子:from multiprocessing import Processimport time def task(): print('老了....') time.sleep(2) print('睡了一会..') if __name__ == '__main__': prin

互斥锁 IPC 生产者消费者

import json import time import random import os from multiprocessing import Process,Lock mutex=Lock() # 互斥锁vs join的区别一: # 互斥锁可以让一部分代码(修改共享数据的代码)串行,而join只能将代码整体串行 def search(): time.sleep(random.randint(1,3)) with open('db.json','r',encoding='utf-8')

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

操作系统发展史(主要的几个阶段) 初始系统 1946年第一台计算机诞生,采用手工操作的方式(用穿孔卡片操作) 同一个房间同一时刻只能运行一个程序,效率极低(操作一两个小时,CPU一两秒可能就运算完了) 联机批处理系统 脱机批处理系统 多道程序系统 1.空间上的复用 ? 多个程序公用一套计算机硬件 2.时间上的复用 ? 切换+保存状态 ? 保存状态:保存当前的运行状态,下次接着该状态继续执行 ? 切换的两种情况 ? (1) 当一个程序遇到 I/O 操作(不需要使用CPU),操作系统会剥夺该程序的C

进程,互斥锁,生产者消费者,线程

进程,互斥锁,生产者消费者,线程 一.僵尸进程与孤儿进程 代码演示 ''' 僵尸进程(有坏处): - 在子进程结束后,主进程没有正常结束,子进程的PID不会被回收. 缺点: - 操作系统中PID号是有限的,比如子进程PID号无法正常回收,则会占用PID号. - 资源浪费 - 若PID号满了,则无法创建新的进程. 孤儿进程(没有坏处): - 在子进程没有结束时,主进程没有"正常结束",子进程PID不会被回收. - 操作系统优化机制(孤儿院): 当主进程意外终止,操作系统会检测是否有正在运

10.22进程互斥锁,队列,堆栈,线程

进程互斥锁 让并发变成串行,牺牲了执行效率,保证了数据的安全. 在程序并发执行时,如果需要修改数据就使用互斥锁. 队列 相当于内存中的空间. 可以存放多个数据,必须排队,遵循先进先出的顺序. from multiprocessing import Queue #调用队列类,实例化队列对象q q = Queue(5) #若传参,队列中就可以存放5个数据 q = Queue() #若不传参,则队列中可以存放无限个数据 q.get() #获取数据 q.put() #添加数据,满了就报错 q.empty

Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信

目录 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 2.僵尸进程和孤儿进程 2.1僵尸进程 2.2孤儿进程 2.3僵尸进程如何解决? 3.互斥锁,锁 3.1互斥锁的应用 3.2Lock与join的区别 4.进程之间的通信 进程在内存级别是隔离的 4.1基于文件通信 (抢票系统) 4.2基于队列通信 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 1.创建进程的两种方式: 函数, 类. 2.pid: os.getpid() os.get

Java使用FileLock实现Java进程互斥锁

原理:JDK的nio包中FileLock实现类似Linux fcntl的文件锁, 可使文件被进程互斥访问.  借助此功能, 可以实现强大的Java进程互斥锁, 从而在应用层面保证同一时间只有惟一的Jar应用进程在运行! 避免某些因素导致jar重复执行, 多个进程产生竞争,破坏业务数据. (当然, 你可以借助类似ubuntu的upstart脚本或者ps -p <pid>之类的做法来做到相同的功能).实现: package test; import java.io.File; import jav

并发无锁队列学习(单生产者单消费者模型)

1.引言 本文介绍单生产者单消费者模型的队列.根据写入队列的内容是定长还是变长,分为单生产者单消费者定长队列和单生产者单消费者变长队列两种.单生产者单消费者模型的队列操作过程是不需要进行加锁的.生产者通过写索引控制入队操作,消费者通过读索引控制出队列操作.二者相互之间对索引是独享,不存在竞争关系.如下图所示: 2.单生产者单消费者定长队列 这种队列要求每次入队和出队的内容是定长的,即生产者写入队列和消费者读取队列的内容大小事相同的.linux内核中的kfifo就是这种队列,提供了读和写两个索引.