进程 是个资源分配单位python
狭义定义: 进程是正在运行的程序的实例linux
广义定义: 进程是一个具备必定独立功能的程序关于某个数据集合的一次运行活动.它是操做系统动态执行的基本单元,在传统的操做系统中,进程便是基本的分配单元,也是基本的执行单元ios
进程概念:数据库
第一,进程是一个实体。每个进程都有它本身的地址空间,通常状况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。
第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时(操做系统执行之),它才能成为一个活动的实体,咱们称其为进程。
进程是操做系统中最基本、重要的概念。是多道程序系统出现后,为了刻画系统内部出现的动态状况,描述系统内部各道程序的活动规律引进的一个概念,全部多道程序设计操做系统都创建在进程的基础上。windows
进程调度 : 就是多个进程(运行中的程序) 在操做系统的控制下被CPU 执行,去享用计算机资源服务器
先来先服务并发
短做业优先app
时间片轮转异步
多级反馈队列socket
进程调度的过程是不可以随意被程序影响的
程序的并行与并发
并行更快
并发只是宏观上的同时执行
进程一共有三个状态:
就绪 运行 阻塞
同步: 就是 好比 洗衣和作饭 按顺序一个一个作 是同步走
异步: 一边洗衣 一边作饭, 这就是异步走
阻塞
非阻塞
进程
pid Process ID 进程ID
ppid parent process id 父进程 ID
父进程 负责回收一些子进程的资源
子进程
在python程序中的进程操做
multiprocess模块
multiprocess.process模块
不是一个模块 而是python中一个操做,管理进程的包
建立进程部分
进程同步部分
进程池部分
进程之间数据分享
process模块是一个建立进程的模块,借助这个模块,就能够完成进程的建立
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化获得的对象,表示一个子进程中的任务(还没有启动) 强调: 1. 须要使用关键字的方式来指定参数 2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'egon',) 4 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18} 5 name为子进程的名称
1 p.start():启动进程,并调用该子进程中的p.run() 2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,咱们自定义类的类中必定要实现该方法 3 p.terminate():强制终止进程p,不会进行任何清理操做,若是p建立了子进程,该子进程就成了僵尸进程,使用该方法须要特别当心这种状况。若是p还保存了一个锁那么也将不会被释放,进而致使死锁 4 p.is_alive():若是p仍然运行,返回True 5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,须要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程
使用process模块建立进程
os.getpid 返回当前进程的id
os.getppid 返回当前父进程的id
import os import time from multiprocessing import Process ##进程模块 def func(): print('in func',os.getpid(),os.getppid()) if __name__ == '__main__': print('in main',os.getpid(),os.getppid()) p1 = Process(target = func ) ##进程对象 p1.start() #向操做系统提交了一个开启子进程的申请 p2 = Process(target = func) #进程对象 p2.start() #想操做系统提交了一个开启子进程的申请 print('主进程的代码执行结束了') 获得结果: in main 6604 12564 主进程 的 代码执行结束了 in func 3584 6604 in func 3036 6604 原理 if __name__ == '__main__' 使用python都是调用操做系统的命令来启动进程 一样视同python 不一样的操做系统的操做是不一样的 对于windows来讲 必要要加 if __name__ == '__main__' 对于linux_ios 来讲,没必要要加 if __name__ == '__main__' 那怎么给子进程里面传参数呢? def func(num): time.sleep(2) print('in func',num,os.getpid(),os.getppid()) if __name__ == '__main__': print('in main',os.getpid(),os.getppid()) p1 = Process(target=func,args=(1,)) # 进程对象 p1.start() # 向操做系统提交了一个开启子进程的申请 p2 = Process(target=func,args=(2,)) # 进程对象 p2.start() # 向操做系统提交了一个开启子进程的申请 print('主进程 的 代码执行结束了')
其余方法和属性
1.开启多个子进程 def func(num): print('in func',num,os.getpid(),os.getppid()) if __name__ == '__main__': print('in main',os.getpid(),os.getppid()) for i in range(10): p = Process(target=func,args=(i,)) p.start() # start不是运行一个程序,而是调用操做系统的命令,要建立子进程 print('主进程 的 代码执行结束了') 2.join方法 def func(num): time.sleep(1) print('in func',num,os.getpid(),os.getppid()) if __name__ == '__main__': print('in main',os.getpid(),os.getppid()) p = Process(target=func,args=(1,)) p.start() # start不是运行一个程序,而是调用操做系统的命令,要建立子进程 p.join() # 阻塞,直到p这个子进程执行完毕以后再继续执行 print('主进程 的 代码执行结束了') 3.一批任务使用join def func(num): print('in func',num,os.getpid(),os.getppid()) if __name__ == '__main__': print('in main',os.getpid(),os.getppid()) p_l = [] for i in range(10): p = Process(target=func,args=(i,)) p.start() # start不是运行一个程序,而是调用操做系统的命令,要建立子进程,非阻塞 p_l.append(p) print(p_l) for p in p_l : p.join() # 阻塞,直到p这个子进程执行完毕以后再继续执行 print('主进程 的 代码执行结束了') 4.is_alive terminate def func(num): time.sleep(2) print('in func',num,os.getpid(),os.getppid()) if __name__ == '__main__': print('in main',os.getpid(),os.getppid()) p1 = Process(target=func,args=(1,)) # 进程对象 p1.start() # 向操做系统提交了一个开启子进程的申请 print(p1.is_alive()) # 检测进程是否在执行任务 p1.terminate() # 强制结束子进程 - 非阻塞 print(p1.is_alive()) # 检测进程是否在执行任务 print('主进程 的 代码执行结束了') 用面向对象的方式开启子进程 class MyProcess(Process): def __init__(self,num): super().__init__() self.num = num def run(self): print('in run ',self.num,os.getpid(),os.getppid()) if __name__ == '__main__': print('in main ', os.getpid(), os.getppid()) p = MyProcess(1) p.start()
进程之间的数据隔离问题
n= 100 def func(): global n n = n-1 return 111 if__name__ =='__main__': n_l = [] for i in range(100): p = Process(target=func) p.start() n_l.append(p) for p in n_l : p.join() print(n) 进程与进程之间的数据是隔离的 内存空间是不能共享的 因此要想进行通讯,必须借助其余手段 且这两个进程都是自愿的
守护进程
是会随着主进程的结束而结束.
主进程建立守护进程.
其一 : 守护进程会在主进程代码执行结束后就终止
其二 : 守护进程内没法再开启子进程,不然抛出异常
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即中止
例一 (建立守护进程) import time
from multiprocessing import Process def func1(): print('begin') time.sleep(3) print('wahaha') if __name__ == '__main__':sad p = Process(target = func1) p.daemon = True ###守护进程的属性,默认是False,若是设置成True,就表示设置这个子进程为一个守护进程 ,,,设置守护进程的操做应该在开启子进程以前 p.start() time.sleep(1) print('主进程') 获得结果: begin 主进程
例二 import time from multiprocessing import Process def func1(): print('begin') time.sleep(3) print('wahaha') def func2(): while True: print('in func2') time.sleep(0.5) if __name__ == '__main__': Process(target = func1).start() p = Process(target = func2) p.daemon = True ##看清楚,是把p搞成了守护进程 p是func2 p.start() time.sleep(1) print('主进程') 设置成守护进程以后,会有什么效果呢? 守护进程会在主进程的代码执行完毕以后直接结束,不管守护进程是否执行完毕
应用
守护进程能够用来作报活
报活 报告你的主进程还活着
守护进程如何向检测机制报活???send/写数据库
为何要用守护机制来报活呢?为何不用主进程来工做呢?
守护进程报活几乎不占用CPU,也不须要操做系统去调度
主进程不能严格每60秒发送一条信息(时间上控制不了)
####全部的进程的基本使用
####进程 :同一时刻能够作多件事情,互相之间不受影响
####
多进程的 socket例子
服务器 import socket from multiprocessing import Process def talk(conn): try: while True: conn.send(b'hello') print(conn.recv(1024)) finally: conn.close() if __name__ =='__main__': sk = socket.socket() sk.bind(('127.0.0.1',9091)) sk.listen() try: while True: conn,addr = sk.accept() Process(target = talk,args= (conn,)).start() finally: sk.close() 客户端 import socket import os sk = socket.socket() sk.connect(('127.0.0.1',9091)) while True: print(sk.recv(1024)) sk.send(str(os.getpid()).encode('utf-8'))