什么是多进程
多进程用于执行多个进程的并行执行。
它可以帮助实现真正的并行性,因为可以同时执行不同的进程,并且每个进程都拥有自己的内存空间。
它使用CPU的独立核心,并且在执行进程间的数据交换时也很有帮助。
与多线程相比,多进程的计算成本更高,因为不使用共享内存空间。
不过,它允许进行独立执行,并克服了全局解释器锁的限制。
上图展示了一个多进程环境,在该环境中,一个主进程创建了两个独立的进程,并为它们分配了不同的工作。
多进程实现
目前对多线程及其实现方式和限制已经有基本的了解。现在,是时候学习多进程的实现以及如何克服这些限制了。
在这里将沿用相同的示例,但不再创建两个独立的线程,而是创建两个独立的进程,并讨论观察结果。
1、导入库:
from multiprocessing import Process
import os
本例将使用multiprocessing
模块来创建独立的进程。
2、计算平方的函数:
该函数将保持不变。只是在这里删除了有关线程信息的打印语句。
def calculate_squares(numbers):
for num in numbers:
square = num * num
print(
f"Square of the number {num} is {square} | PID of the process {os.getpid()}"
)
3、主函数:
主函数有一些修改。只是创建了一个独立的进程,而不是线程。
if __name__ == "__main__":
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
half = len(numbers) // 2
first_half = numbers[:half]
second_half = numbers[half:]
p1 = Process(target=calculate_squares, args=(first_half,))
p2 = Process(target=calculate_squares, args=(second_half,))
p1.start()
p2.start()
p1.join()
p2.join()
输出:
Square of the number 1 is 1 | PID of the process 1125
Square of the number 2 is 4 | PID of the process 1125
Square of the number 3 is 9 | PID of the process 1125
Square of the number 4 is 16 | PID of the process 1125
Square of the number 5 is 25 | PID of the process 1126
Square of the number 6 is 36 | PID of the process 1126
Square of the number 7 is 49 | PID of the process 1126
Square of the number 8 is 64 | PID of the process 1126
可以观察到,每个列表都由一个独立的进程执行,它们具有不同的进程ID。
为了检查进程是否已并行执行,需要创建一个单独的环境,下面我们将讨论这一点。
计算是否使用多进程的运行时间
为了检查是否获得了真正的并行性,在这里将计算使用和不使用多进程的算法运行时间。
为此,需要一个包含超过10^6个整数的大型整数列表。
可以使用random
库生成一个列表,此处将使用Python的time
模块来计算运行时间。
下面是实现的代码,代码本身很容易理解,也可以随时查看代码注释。
from multiprocessing import Process
import os
import time
import random
def calculate_squares(numbers):
for num in numbers:
square = num * num
if __name__ == "__main__":
numbers = [
random.randrange(1, 50, 1) for i in range(10000000)
] # 创建一个包含10^7个整数的随机列表。
half = len(numbers) // 2
first_half = numbers[:half]
second_half = numbers[half:]
# ----------------- 创建单进程环境 ------------------------#
start_time = time.time() # 开始计时(不使用多进程)
p1 = Process(
target=calculate_squares, args=(numbers,)
) # 单进程P1执行整个列表
p1.start()
p1.join()
end_time = time.time() # 结束计时(不使用多进程)
print(f"Execution Time Without Multiprocessing: {(end_time-start_time)*10**3}ms")
# ----------------- 创建多进程环境 ------------------------#
start_time = time.time() # 开始计时(使用多进程)
p2 = Process(target=calculate_squares, args=(first_half,))
p3 = Process(target=calculate_squares, args=(second_half,))
p2.start()
p3.start()
p2.join()
p3.join()
end_time = time.time() # 结束计时(使用多进程)
print(f"Execution Time With Multiprocessing: {(end_time-start_time)*10**3}ms")
输出:
Execution Time Without Multiprocessing: 619.8039054870605ms
Execution Time With Multiprocessing: 321.70287895202637ms
可以观察到,使用多进程的时间几乎是不使用多进程时间的一半。
这表明这两个进程在同一时间内并行执行,并展示了真正的并行性行为。