进程
1 什么是进程
进程指的是一个正在进行/运行的程序,进程是用来描述程序执行过程的虚拟概念
进程vs程序
程序:一堆代码
进程:程序的执行的过程
进程的概念起源于操作系统,进程是操作系统最核心的概念,操作系统其它所有的概念都是围绕进程来
操作系统理论:
操作系统是一个协调\管理\控制计算机硬件资源与应用软件资源的一段控制程序
有两大功能:
1. 将复杂的硬件操作封装成简单的接口给应用程序或者用户去使用
2. 将多个进程对硬件的竞争变得有序
操作系统发展史
并发: 多个任务看起来是同时运行的
串行:一个任务完完整整地运行完毕,才能运行下一个任务
多道技术:(复用=>共享/共用)
1. 空间上的复用:多个任务复用内存空间
2. 时间上的复用:多个任务复用cpu的时间
1. 一个任务占用cpu时间过长会被操作系统强行剥夺走cpu的执行权限:比起串行执行反而会降低效率
2. 一个任务遇到io操作也会被操作系统强行剥夺走cpu的执行权限:比起串行执行可以提升效率
2 为何用进程
实现并发
3 如何用进程
开启子进程的方式一: #调研系统类地点方式
from multiprocessing import Process
import time
def task(name):
print('%s is running' %name)
time.sleep(3)
print('%s is done' %name)
# 在windows系统上,开启子进程的操作必须放到if __name__ == '__main__'的子代码中
if __name__ == '__main__':
p=Process(target=task,args=('egon',)) #Process(target=task,kwargs={'name':'egon'})
p.start() # 只是向操作系统发送了一个开启子进程的信号
p.join() # join:让主进程在原地等待,等待子进程运行完毕,不会影响子进程的执行(****)
print('主') # join:让主进程等待子进程运行完毕,即主进程在原地阻塞,而不影响子进程的运行
开启子进程的方式二: #自定义类的方式
from multiprocessing import Process
import time
class Myprocess(Process):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print('%s is running' %self.name)
time.sleep(3)
print('%s is done' %self.name)
# 在windows系统上,开启子进程的操作必须放到if __name__ == '__main__'的子代码中
if __name__ == '__main__':
p=Myprocess('egon') #p为进程对象
p.start() # 只是向操作系统发送
4 进程相关其它操作
1. 进程pid:每一个进程在操作系统内都有一个唯一的id号,称之为pid
2.from multiprocessing import Process,current_process
current_process() #当前进程的pid,相当于os.getpid().其中os.getppid():查看父进程的pid
3. 进程对象其他相关的属性或方法
p.terminate() 结束进程p
p.is_alive() 查看进程p是否结束
4.僵尸进程和孤儿进程:僵尸进程指死掉的进程. 孤儿进程:父进程死掉,子进程变成孤儿进程,此时父进程为:INIT
5.守护进程: 本质就是一个"子进程",该"子进程"的生命周期<=被守护进程的生命周期
p.daemon=True #设置进程p 为守护进程
6.互斥锁 :from multiprocessing import Process,Lock
mutex = Lock() #创建锁对象
for i in range(10):
p=Process(target=task,args=('路人%s' %i,mutex)) #创建进程时把互斥锁传进之进程中
p.start()
def task(name,mutex):
search(name) #并发
mutex.acquire() #开始上锁
get(name) #变成串行
mutex.release() #解锁
join VS 互斥锁
join:是将代码整体串行
互斥锁:是将代码中的关于修改共享数据的 那一小部分代码变成串行,牺牲了效率保证数据安全
5.进程间通信(ICP机制)
#队列=管道+锁 from multiprocessing import Queue
q=Queue() #创建队列
q.put(['first',]) #向队列中传入一个元素
q.get() #向队列中取出一个元素
q=Queue(3) #队列中最大元素的个数
q.put(['first',],block=True,timeout=3) #队列已满时等待3秒,如果block=False,若队列已满直接报错
q.get(block=True,timeout=3) #队列为空时等待3秒,如果block=False,若队列为空直接报错
q.put_nowait(1) #等效于q.put(1,block=False)
q.get_nowait()) #等效于q.get(block=false)
6.生产者消费者模型(******)
1. 什么是生产者消费者模型
生产者:代指生产数据的任务
消费者:代指处理数据的任务
该模型的工作方式:
生产生产数据传递消费者处理
实现方式:生产者---->队列<------消费者
2. 为何要用
当程序中出现明细的两类任务,一类负责生产数据,一类负责处理数据
就可以引入生产者消费者模型来实现生产者与消费者的解耦合,平衡生产能力与消费能力,从提升效率
3. 如何用
import time,random
from multiprocessing import Process,Queue
def producer(name,food,q):
for i in range(3):
res='%s%s' %(food,i)
time.sleep(random.randint(1,3)) #模拟生产数据的时间
q.put(res)
print('厨师[%s]生产了<%s>' %(name,res))
def consumer(name,q):
while True:
res=q.get()
if res is None:break
time.sleep(random.randint(1,3)) #模拟处理数据的时间
print('吃货[%s]吃了<%s>' %(name,res))
if __name__ == '__main__':
q=Queue()
# 生产者们
p1=Process(target=producer,args=('小Egon','泔水',q))
p2=Process(target=producer,args=('中Egon','屎包子',q))
p3=Process(target=producer,args=('大Egon','腰子汤',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)
q.put(None)
print('主')
4.补充了解第二种实现方式:
import time,random
from multiprocessing import Process,JoinableQueue #可调用队列
def producer(name,food,q):
for i in range(3):
res='%s%s' %(food,i)
time.sleep(random.randint(1,3)) #模拟生产数据的时间
q.put(res)
print('厨师[%s]生产了<%s>' %(name,res))
def consumer(name,q):
while True:
res=q.get()
time.sleep(random.randint(1,3)) #模拟处理数据的时间
print('吃货[%s]吃了<%s>' %(name,res))
q.task_done()
if __name__ == '__main__':
q=JoinableQueue() #相当与可调用的q=Queue()
# 生产者们
p1=Process(target=producer,args=('小Egon','泔水',q))
p2=Process(target=producer,args=('中Egon','屎包子',q))
p3=Process(target=producer,args=('大Egon','腰子汤',q))
# 消费者们
c1=Process(target=consumer,args=('刘清正',q))
c2=Process(target=consumer,args=('吴三江',q))
c1.daemon=True #设定为守护进程
c2.daemon=True #设定为守护进程
#运行进程
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
#等待生产者进程结束才继续主进程
p1.join()
p2.join()
p3.join()
q.join() # 主进程等q结束,即q内数据被取干净了
print('主')
转载于:https://www.cnblogs.com/wu-jia/p/9599964.html