1.概念
- 进程是对进行中的程序的一种称呼.
- 多个进程之间互相数据隔离.
- 进程是操作系统中最小的资源分配单位.
2.进程的三种状态
就绪:当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态.
运行:当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态.
阻塞:由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态.
3.守护进程
3.1特点
守护进程是一种特殊的进程,会随着主进程代码的结束而结束.
注:不是随着主进程的结束而结束,主进程负责子进程占用资源的回收,所以主进程会在最后结束,但守护进程也是子进程,无法在主进程之后结束,所以只能在主进程代码结束时就认为主进程已经结束.
3.2设置方法
在创建进程时,将daemon参数的值设置为True.
p = Process(target = func,daemon = True) 或 p.daemon = True
4.进程池
4.1定义
创建进程和销毁进程都需要消耗系统资源,所以在面对大量的任务时,就需要以固定少量的进程来执行大量的任务,来避免创建和销毁进程过程中造成的系统资源浪费.
这就需要进程池来完成.
4.2回调函数
在使用apply_async时,可以加入callback参数来设置回调函数,回调函数由父进程执行,将进程池得到的返回值作为参数传入回调函数中运行.
4.3用法
from multiprocessing import Pool
def func(i):
return i + 1
def callback_func(i):
print(i)
if __name__ == '__main__':
p = Pool(4)
for i in range(10000):
p.apply_async(func,args=(i,),callback=callback_func)
p.close()
p.join()
以上为apply_async的用法.
map是一种比较简便的使用方法,功能有限.
apply与apply_async类似,但apply是同步运行,作用不大.
5.IPC
IPC(Inter-Process Communication),中文名称为进程间通信.
由于进程之间互相数据隔离,所以只能通过特殊手段来实现数据在多个进程间的传播与交换.
5.1管道
管道底层基于socket的文件家族通信,通过实例化Pipe类得到一个管道的两端,进程之间可以通过管道的两端进行数据的交换.使用方法与socket有相似之处.
但是管道在多个线程同时使用时存在数据不安全的问题,所以使用时要加锁.
from multiprocessing import Process,Pipe
def sender(pipe_obj):
print('sender')
pipe_obj.send('2333')
def receiver(pipe_obj):
print('receiver',pipe_obj.recv())
if __name__ == '__main__':
print('main')
c1,c2 = Pipe()
p1 = Process(target= sender,args=(c1,))
p2 = Process(target= receiver,args=(c2,))
p1.start()
p2.start()
5.2队列
队列底层由Pipe和锁实现.
队列是数据安全的,所以使用队列的情况比较多.
from multiprocessing import Process,Queue
def consumer(q):
print('consumer',q.get())
def producer(q):
print('producer')
q.put('2333')
if __name__ == '__main__':
print('main')
q = Queue()
p1 = Process(target=consumer,args=(q,))
p2 = Process(target=producer,args=(q,))
p1.start()
p2.start()
还有一种Joinable队列,Joinable队列拥有join方法,join方法可以造成阻塞,直到队列为空,get数据后需要通过task_done通知队列.