python-面向运行时性能优化-multiprocessing
一:多进程介绍
1> 基本思想
算法可以划分为不同的 workers-处理器处理,可以根据机器核数并行部署运行;
并行计算涉及在处理器的多个核心之间执行多个任务,这意味着这些任务是同时执行的,同时并考虑并行方式是否优化可以加快我们的计算速度;
结构组成由-程序、数据和进程控制块组成
2> 模式分类
模式 | 含义 |
---|---|
完全平行 | 任务可以独立运行,不需要相互通信 |
共享内存并行 | 程(或线程)需要通信,因此它们共享一个全局地址空间 |
消息传递 | 进程需要在需要时共享消息。 |
3> 引入进程原因
序列 | 原因 |
---|---|
1 | 为了提高资源利用率和系统处理能力,现阶段计算机系统都是多道程序系统,即多道程序并发执行。 |
2 | 优化系统资源,方便计算机调度,避免系统运算紊乱。 |
3 | 进程是一种数据结构,能够清晰的刻画动态系统的内在规律,增加程序运行时的动态性 |
4> 进程特征
特征 | 注释 |
---|---|
动态性 | 进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。 |
并发性 | 任何进程都可以同其他进程一起并发执行。 |
独立性 | 进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位。 |
异步性 | 由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进 |
二:multiprocessing模块
1> multiprocessing 介绍
multiprocessing 是一个支持使用与 threading 模块类似的 API 来产生进程的包;
multiprocessing 包同时提供了本地和远程并发操作,通过使用子进程而非线程有效地绕过了 全局解释器锁;
multiprocessing 模块还引入了在 threading 模块中没有的API。一个主要的例子就是 Pool 对象,它提供了一种快捷的方法,赋予函数并行化处理一系列输入值的能力,可以将输入数据分配给不同进程处理(数据并行);
1. multiprocessing demo
import multiprocessing
import time
def worker():
print('Starting to sleep')
time.sleep(1)
print('Done sleeping')
if __name__ == '__main__':
tic = time.time()
# 创建子进程
p1 = multiprocessing.Process(target= worker)
p2 = multiprocessing.Process(target= worker)
# 启动子进程
p1.start()
p2.start()
# 等待子进程结束
p1.join()
p2.join()
toc = time.time()
print(toc-tic)
================
Starting to sleep
Starting to sleep
Done sleepingDone sleeping
1.1136295795440674
注释:
worker函数将在子进程中执行。首先,创建了一个Process对象,指定target参数为worker函数;
通过调用start方法启动子进程,最后调用join方法等待子进程结束;
2> multiprocessing启动方法
根据不同的平台, multiprocessing 支持三种启动进程的方法;
方法 | 解释 |
---|---|
spawn | 可在 Unix 和 Windows 上使用。 Windows 和 macOS 上的默认设置;父进程启动一个新的Python解释器进程。 子进程将只继承运行进程对象的run()方法所需的资源。 特别是,不会继承父进程中不必要的文件描述符和句柄。 与使用fork或forkserver相比,使用这种方法启动进程相当慢。 |
fork | 只存在于 Unix。 Unix 中的默认值;父进程使用 os.fork() 来产生 Python 解释器分叉。子进程在开始时实际上与父进程相同。父进程的所有资源都由子进程继承; |
forkserver | 可在Unix平台上使用,支持通过Unix管道传递文件描述符;程序启动并选择 forkserver 启动方法时,将启动服务器进程。 从那时起,每当需要一个新进程时,父进程就会连接到服务器并请求它分叉一个新进程。 分叉服务器进程是单线程的,因此使用 os.fork() 是安全的 |
3> Process 类
1. Process demo
在 multiprocessing 中,通过创建一个 Process 对象然后调用它的 start() 方法来生成进程。 Process 和 threading.Thread API 相同;
from multiprocessing import Process
def say(name):
print('hello', name)
if __name__ == '__main__':
p = Process(target=say, args=('TOM',))
p.start()
p.join()
=============
hello TOM
info 信息打印
from multiprocessing import Process
import os
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid())
print('process id:', os.getpid())
def say(name):
info('function say')
print('hello', name)
if __name__ == '__main__':
info('main line')
p = Process(target=say, args=('TOM',))
p.start()
p.join()
===========
main line
modul