【Python并发】【Python多进程(一)】创建进程
【Python并发】【Python多进程(二)】进程间通信
【Python并发】【Python多进程(三)】进程间数据共享
【Python并发】【Python多进程(四)】进程同步
一. 多进程模块multiprocessing
在Python的os模块中封装了许多的系统调用,其中封装了Unix/Linux系统中的fork()系统调用,其作用是复制当前的进程来产生新进程,当前进行称为“父进程”,新进程称为“子进程”。但是,在Windows系统中是没有fork()系统调用的。因此,Python提供了跨平台的多进行模块"multiprocessing"。
二. 使用Process类创建进程
2.1 直接使用Process类
from multiprocessing import Process
def say_hi(name):
print('hi', name+'!')
if __name__ == '__main__':
p = Process(target=say_hi, args=('tony',)) # 指定进程执行的函数并传递参数
p.start() # 启动进程
p.join() # 使主进程等待子进程(也就是定义的p)结束后运行,用于进程同步
输出:
hi tony!
2.2 继承Process类
from multiprocessing import Process
class MyProcess(Process):
def __init__(self, name):
super(MyProcess, self).__init__()
self.name = name
def run(self): # 重写父类的run()方法,其中应包含进程将要执行的代码
print('hi', self.name + '!')
if __name__ == '__main__':
p = MyProcess('tony')
p.start()
p.join()
输出:
hi tony!
2.3 进阶例子:显示进程信息
from multiprocessing import Process
import os
def process_info(message):
print(message)
print('当前模块:', __name__)
print('当前进程的父进程id: ', os.getppid())
print('当前进程的id: ', os.getpid())
def say_hi(name):
process_info('say_hi')
print('hi', name+'!')
if __name__ == '__main__':
p = Process(target=say_hi, args=('tony',))
p.start()
p.join()
输出:
say_hi
当前模块: __mp_main__
当前进程的父进程id: 22300
当前进程的id: 15624
hi tony!
2.4 Porcess对象常用的方法与属性
- name:进程的名称;
- daemon:布尔值,是否是守护进程;
- pid:进程ID;
- exitcode:进程退出码;
- run():表示进程所要做的事情,通过向参数taget指定一个函数的方式指定run的行为,或者在子类中重载该方法;
- start():启动进程;
- join():阻塞当前进程,直至调用该方法的进程结束;
- is_alive():判断进程是否还活着;
- terminate():终止进程;
- close():关闭Process对象,释放与之关联的资源;
from multiprocessing import Process
import time
import signal
p = Process(target=time.sleep, args=(10, ))
print(p, p.is_alive()) # <Process(Process-1, initial)> False
p.start()
print(p, p.is_alive()) # <Process(Process-1, started)> True
p.terminate()
time.sleep(1)
print(p, p.is_alive()) # <Process(Process-1, stopped[SIGTERM])> False
print(p.exitcode == -signal.SIGTERM) # True
2.5 进程池Pool
进程池用于批量的创建进程
from multiprocessing import Pool
import os
def square(x):
return x**2
if __name__ == '__main__':
print('父进程:{}'.format(os.getppid()))
with Pool(processes=4) as pool: # 指定进程池中包含的进程数
print(pool.apply(square, (2,))) # 阻塞式调用
res1 = pool.apply_async(square, (3,)) # 异步调用
print(res1.get(timeout=2)) # 获得返回值,2秒内未返回则抛异常
# 启动多个异步进程
multiple_results = [pool.apply_async(square, (i,)) for i in range(3)]
print([res.get(timeout=1) for res in multiple_results])
print(pool.map(square, range(3))) # map的并行版本
for i in pool.imap(square, range(3)): # pool.map的迭代器版本
print(i)
for i in pool.imap_unordered(square, range(3)): # imap的无序版本
print(i)
pool.close()
pool.join() # join()只能在close()后调用,因此pool.close()后表示不再接受新的进程了
print("所有子进程结束!")