Python多进程multiprocessing、进程池用法实例分析
1. 前言
在Python中,我们可以使用线程(threading)和进程(multiprocessing)来实现多任务。相对于线程而言,进程更加稳定、安全,并且能利用多核CPU更充分。
本文将重点讲解Python多进程模块(multiprocessing)和进程池用法实例分析,帮助大家深入了解Python多进程编程的实现细节。
2. Python多进程multiprocessing模块用法
Python中的multiprocessing模块可以轻松实现多进程编程。下面是一段使用multiprocessing实现简单的多进程并发的示例代码:
import multiprocessing
def worker():
"""子进程要执行的函数"""
print("Worker start")
print("Worker end")
if __name__ == '__main__':
print("Main process start")
p = multiprocessing.Process(target=worker)
p.start() # 启动子进程
p.join() # 等待子进程完成
print("Main process end")
其中,multiprocessing.Process
可以启动一个子进程,p.start()
启动子进程,p.join()
等待子进程完成。
2.1 multiprocessing中的进程间通信
使用队列(Queue)可以很方便地实现Python进程间通信。下面是一个简单的例子:
from multiprocessing import Process, Queue
def f(q):
q.put('hello')
if __name__ == '__main__':
q = Queue() # 定义进程共享的队列
p = Process(target=f, args=(q,))
p.start()
print(q.get()) # 从进程共享的队列中读出数据
p.join()
在这个示例中,我们使用队列Q传递数据。首先,我们需要使用Queue()
定义一个共享的队列。然后,我们在子进程中把数据'hello'放入队列中。在主进程中,我们使用q.get()
从队列中读取这个数据。最后,我们等待子进程结束。
2.2 multiprocessing中的共享内存
共享内存是多进程编程中非常常见的问题,因为多个进程要共用同一块内存区域。Python中的multiprocessing模块同样可以很好地支持共享内存操作。下面是一个共享内存的示例:
import multiprocessing
def f(n, a):
n.value = 3.1415926
for i in range(len(a)):
a[i] = -a[i]
if __name__ == '__main__':
num = multiprocessing.Value('d', 0.0) # 定义共享内存变量num
arr = multiprocessing.Array('i', range(10)) # 定义共享内存数组arr
print('Before:', num.value, arr)
p = multiprocessing.Process(target=f, args=(num, arr))
p.start()
p.join()
print('After:', num.value, arr)
在这个示例中,我们定义了一个共享内存变量num
和一个共享内存数组arr
。在子进程中,我们把共享内存变量num
改为了3.1415926,把共享内存数组中的每个元素都改为了相反数。在主进程中,我们打印出了改变前和改变后的共享内存变量和数组。
3. Python进程池用法实例分析
使用进程池的好处在于可以循环利用多个进程,从而避免了频繁创建和销毁进程的开销。下面是一个可以循环利用进程的简单的进程池的示例(使用multiprocessing.Pool):
import multiprocessing
def f(x):
return x*x
if __name__ == '__main__':
with multiprocessing.Pool(processes=4) as pool: # 定义进程池
results = pool.map(f, range(10)) # 使用进程池执行f函数
print(results)
在这个示例中,我们使用了multiprocessing.Pool
定义了一个拥有4个进程的进程池。使用pool.map
方法执行f函数,得到返回值列表results。
下面再给出一个进程池的实例,使用multiprocessing.Pool
复制一个文件夹下的所有文件:
import multiprocessing
import os.path as osp
import shutil
def copy_file(file_path, out_path):
shutil.copyfile(file_path, osp.join(out_path, osp.basename(file_path)))
def copy_folder(src_folder, out_folder):
# 在目标文件夹中创建一个与源文件夹相同的文件结构
dst_folder = osp.join(out_folder, osp.basename(src_folder))
if not osp.exists(dst_folder):
shutil.copytree(src_folder, dst_folder)
# 使用进程池递归复制文件
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool:
for root, _, files in os.walk(src_folder):
for file in files:
file_path = osp.join(root, file)
pool.apply_async(copy_file, args=(file_path, dst_folder))
pool.close() # 关闭进程池
pool.join() # 等待进程池中的所有进程完成
print(f'Folder {src_folder} copied to {dst_folder} successful!')
if __name__ == '__main__':
copy_folder('/path/to/src/folder', '/path/to/out/folder')
在这个示例中,我们使用了shutil.copytree
递归复制源目录。然后使用进程池multiprocessing.Pool
复制源目录下的所有文件:对于每个文件,我们都将其复制到目标目录,并在进程池中并行处理。使用进程池的好处在于可以充分利用多核CPU,从而提高文件复制的速度。
4. 结论
在Python中,使用多进程编程可以很容易地实现并发处理,同时利用多核CPU提高程序处理速度。本文介绍了Python的multiprocessing模块和进程池(multiprocessing.Pool)的基本用法及示例,希望对大家学习Python多进程编程有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python多进程multiprocessing、进程池用法实例分析 - Python技术站