198 lines
4.3 KiB
Markdown
198 lines
4.3 KiB
Markdown
# Python 中的多重处理
|
||
|
||
> 原文:<https://www.askpython.com/python-modules/multiprocessing-in-python>
|
||
|
||
嘿伙计们!在本文中,我们将学习 Python 中的多重处理。那么,我们开始吧。
|
||
|
||
## 什么是多重处理?
|
||
|
||
多重处理是 python 中的一个包,它支持生成利用 Python API 的进程的能力。它类似于 Python 中的线程模块。
|
||
|
||
## 理解 Python 中的多重处理
|
||
|
||
多处理器是指计算机有一个以上的中央处理器。如果一台计算机只有一个多核处理器,可以使用 Python 中的[多线程并行运行任务。](https://www.askpython.com/python-modules/multithreading-in-python)
|
||
|
||
多处理器系统能够同时支持多个处理器。为了找到我们系统中可用的 CPU 内核的数量,我们使用了 ***mp.cpu_count()*** 函数。
|
||
|
||
在本文中,我们将使用 Python 的多重处理模块
|
||
|
||
**下面是使用多处理模块在 Python 中查找处理器数量的示例代码:**
|
||
|
||
```py
|
||
import multiprocessing as mp
|
||
|
||
print(mp.cpu_count())
|
||
|
||
```
|
||
|
||
输出: **12**
|
||
|
||
这里的计数是多个处理器之间的内核总数。
|
||
|
||
**该模块的四个最重要的类是-**
|
||
|
||
* 流程类
|
||
* 锁定级
|
||
* 队列类别
|
||
* 池类
|
||
|
||
让我们分别看看这些类中的每一个…
|
||
|
||
### 1.流程类
|
||
|
||
进程是当前进程的分叉副本。它创建一个新的进程标识符,任务作为独立的子进程运行。
|
||
|
||
***start()*** 和 ***join()*** 函数都属于这个类。为了在进程中传递一个参数,我们使用 ***args*** 关键字。
|
||
|
||
start()函数示例-
|
||
|
||
在这里,我们创建了一个函数 *calc_square* 和 *calc_cube* ,分别用于求数字的平方和立方。在主函数中,我们创建了对象 *p1* 和 *p2* 。 *p1.start()* 和 *p2.start()* 将启动函数,调用 *p1.join()和 p2.join* 将终止进程。
|
||
|
||
```py
|
||
import time
|
||
import multiprocessing
|
||
|
||
def calc_square(numbers):
|
||
for n in numbers:
|
||
print('square ' + str(n*n))
|
||
|
||
def calc_cube(numbers):
|
||
for n in numbers:
|
||
print('cube '+ str(n*n*n))
|
||
|
||
if __name__ == "__main__":
|
||
arr=[2,3,8,9]
|
||
p1=multiprocessing.Process(target=calc_square,args=(arr,))
|
||
p2=multiprocessing.Process(target=calc_cube,args=(arr,))
|
||
|
||
p1.start()
|
||
p2.start()
|
||
|
||
p1.join()
|
||
p2.join()
|
||
|
||
print("Done")
|
||
|
||
```
|
||
|
||
输出:
|
||
|
||
```py
|
||
square 4
|
||
square 9
|
||
square 64
|
||
square 81
|
||
cube 8
|
||
cube 27
|
||
cube 512
|
||
cube 729
|
||
Done
|
||
|
||
```
|
||
|
||
### 2.锁定级
|
||
|
||
lock 类允许代码被锁定,以确保没有其他进程可以执行类似的代码,直到它被释放。
|
||
|
||
要认领锁, ***使用获取()*** 函数,要释放锁, ***使用释放()*** 函数。
|
||
|
||
```py
|
||
from multiprocessing import Process, Lock
|
||
|
||
lock=Lock()
|
||
def printer(data):
|
||
lock.acquire()
|
||
try:
|
||
print(data)
|
||
finally:
|
||
lock.release()
|
||
|
||
if __name__=="__main__":
|
||
items=['mobile','computer','tablet']
|
||
for item in items:
|
||
p=Process(target=printer,args=(item,))
|
||
p.start()
|
||
|
||
```
|
||
|
||
输出
|
||
|
||
```py
|
||
mobile
|
||
computer
|
||
tablet
|
||
|
||
```
|
||
|
||
### 3.队列类别
|
||
|
||
队列是一种使用先进先出(FIFO)技术的数据结构。它帮助我们使用本地 Python 对象执行进程间通信。
|
||
|
||
当作为参数传递时,队列使进程能够使用共享数据。
|
||
|
||
***put()*** 函数用于向队列中插入数据, ***get()*** 函数用于从队列中消耗数据。
|
||
|
||
```py
|
||
import multiprocessing as mp
|
||
|
||
def sqr(x,q):
|
||
q.put(x*x)
|
||
|
||
if __name__ == "__main__":
|
||
q=mp.Queue() # Instance of queue class created
|
||
processes=[mp.Process(target=sqr,args=(i,q))for i in range (2,10)] # List of processes within range 2 to 10
|
||
for p in processes:
|
||
p.start()
|
||
|
||
for p in processes:
|
||
p.join()
|
||
|
||
result = [q.get() for p in processes]
|
||
print(result)
|
||
|
||
```
|
||
|
||
输出:
|
||
|
||
```py
|
||
[4, 9, 16, 25, 36, 64, 49, 81]
|
||
|
||
```
|
||
|
||
### 4.池类
|
||
|
||
pool 类帮助我们针对多个输入值并行执行一个函数。这个概念叫做数据并行。
|
||
|
||
这里,数组[5,9,8]被映射为函数调用中的输入。pool.map()函数用于传递多个参数的列表。
|
||
|
||
```py
|
||
import multiprocessing as mp
|
||
|
||
def my_func(x):
|
||
print(x**x)
|
||
|
||
def main():
|
||
pool = mp.Pool(mp.cpu_count())
|
||
result = pool.map(my_func, [5,9,8])
|
||
|
||
if __name__ == "__main__":
|
||
main()
|
||
|
||
```
|
||
|
||
输出:
|
||
|
||
```py
|
||
3125
|
||
387420489
|
||
16777216
|
||
|
||
```
|
||
|
||
## 结论
|
||
|
||
在本文中,我们学习了 Python 中多处理的四个最重要的类——进程、锁、队列和池,它们可以更好地利用 CPU 内核并提高性能。
|
||
|
||
## 参考
|
||
|
||
[官方模块文档](https://docs.python.org/3/library/multiprocessing.html) |