简介
- 进程:资源调度的基本单位,亦是一个程序在一个数据集上的一次动态执行过程,如下每一个应用程序即一个进程。同时一个主进程下,可能会有多个子进程。

并发与并行
进程就像工厂(即CPU核心数,一般为8核,4核等),为程序进行工作,当工厂数量很多的时候,可以一个工厂做一个程序的工作,称之为并行。

如果CPU是单核,但是想要同时运行多个应用,就需要再两个程序间切换,只是切换的速度特别快,人眼一般体会不到,这就称之为并发。

普通多函数
import multiprocessingimport timedef func1():while True:print("running func1")time.sleep(1)def func2():while True:print("running func2")time.sleep(1)if __name__ == '__main__':func1()func2()
- 运行结果:

- 如上可知,程序一直执行func1,造成阻塞。不会运行func2,如果想要func1和func2同时运行,可以使用多进程。
阻塞与非阻塞
创建子进程
- p = multiprocessing.Process(target=func1, args=())
- 开启进程
- p.start()
- 查看进程
- os.getpid()
- 等待子进程结束 timeout 等待超时
- p.join(timeout=5)
- 关闭进程
- p.close()
- 守护进程 再主进程结束后结束子进程
- p.daemon = True
import multiprocessingimport timeimport osdef func1():print("当前进程:", os.getpid())for i in range(3):print("running func1")time.sleep(1)def func2():print("当前进程:", os.getpid())for i in range(3):print("running func2")time.sleep(1)if __name__ == '__main__':p = multiprocessing.Process(target=func1, args=())p1 = multiprocessing.Process(target=func2, args=())# p.daemon = True# p1.daemon = Trueprint("主进程:", os.getpid())p.start()p1.start()p.join()p1.join()p.close()p1.close()print("程序结束!")
- 运行结果:

- 由上图可知,主进程先执行,然后使用start开启子进程,主进程等待子进程结束之后再结束!
- 如果使用了daemon的话,主进程不等待子进程运行完,就结束主进程
继承方式
import multiprocessingimport timeimport osclass P1(multiprocessing.Process):def run(self):print("当前进程:", os.getpid())for i in range(3):print("running func1")time.sleep(1)class P2(multiprocessing.Process):def run(self):print("当前进程:", os.getpid())for i in range(3):print("running func2")time.sleep(1)if __name__ == '__main__':p1 = P1()p2 = P2()p1.daemon = Truep2.daemon = Truep1.start()p2.start()print("主进程:", os.getpid())time.sleep(2)print("程序结束!")

如上所示,使用了守护进程,在子进程还未结束的时候,主进程执行结束后即程序结束。主要守护进程需要在进程开启前使用
使用进程池
实例化
- pool = multiprocessing.Pool()
- 向进程池添加任务异步执行
- pool.apply_asnyc(func=func, args=())
- 关闭进程池 不能继续添加任务
- pool.close()
- 主进程等待子进程结束
- pool.join()
import multiprocessingimport timeimport osdef func1(num):print("当前进程:", os.getpid())for i in range(num):print(f"running func1 {num}")time.sleep(1)def func2(num):print("当前进程:", os.getpid())for i in range(num):print(f"running func2 {num}")time.sleep(1)if __name__ == '__main__':pool = multiprocessing.Pool(1)pool.apply_async(func=func1, args=(1,))pool.apply_async(func=func2, args=(2,))pool.close()pool.join()

- 需要注意参数元组传递方式
进程间通信
- 进程与进程之间相互独立,资源不共享。进程与进程之间传递信息,可以使用队列,类似于列表可以存放数据,不过是先进先出。
- 导包
- from multiprocessing import Queue
- 实例化
- q = Queue()
- 常用方法
- q.put() 向队列添加一个数据 如果队列满了则阻塞
- q.get() 从队列中取出一个数据 如果队列为空则阻塞
- q.qsize() 查看队列大小
- q.empty() 判断队列是否为空
- q.put_nowait() 添加一个数据,如果队列满了则报错
- q.get_nowait() 获取一个数据,如果队列为空则报错 ```python from multiprocessing import Queue import multiprocessing import time import os
- 导包
def func1(q): print(“当前进程:”, os.getpid())
for i in range(3):q.put(i)print(f"running func1 put {i}")time.sleep(1)
def func2(q): time.sleep(1) print(“当前进程:”, os.getpid())
while q.qsize():n = q.get()print(f"running func2 get {n}")time.sleep(1)
if name == ‘main‘: q = Queue()
p = multiprocessing.Process(target=func1, args=(q,))p1 = multiprocessing.Process(target=func2, args=(q, ))print("主进程:", os.getpid())p.start()p1.start()p.join()p1.join()p.close()p1.close()print("程序结束!")
```
运行结果

进程之间虽然不共享资源 ,但是共享一套文件系统,比如对同一文件进行写入的时候,必然带来竞争导致错乱,需要对进程进行控制,需要用到进程锁
- 使用:
- 导包
- from multiprocssing import Lock
- 进程池导包方式
- from multiprocssing.Manager() import Lock
- 实例化
- mutex = Lock()
- 方法
- mutex.aquire() 锁定
- mutex。release() 释放
- 导包
