“进程是资源分配的最小单位,线程是CPU调度的最小单位”
多进程
多进程是指一个程序能够同时运行调度多个任务,同时这里有一个虚拟内存的概念,每一个开启的进程都能够“看到”自己有一片内存空间,这片空间拥有所以的内存空间,可以来运行任务。所以多进程的优缺点如下:
优势:
- 并行执行:不同的进程可以同时执行,提高了程序的运行效率。
- 独立性:每个进程有独立的内存空间和执行环境,不会相互干扰。
- 可靠性:如果一个进程崩溃,其他进程仍然可以继续执行。
劣势:
- 资源占用:每个进程都需要独立的内存空间和执行环境,占用系统资源较大。
- 通信困难:由于进程之间独立性较高,进程之间的通信相对复杂。
多线程
为了更清楚了解多线程,我们需要先了解两个线程中重要的概念“内核线程与用户线程”。
内核线程是由操作系统内核创建和管理的。内核线程在操作系统内核的上下文中运行,可以直接访问和操作系统的资源和功能。特点有三点,第一,每一个内核线程都相对独立,因为不属于任何用户管理;第二,对资源的访问更加方便快捷,因为是由操做系统来管理,所以对于硬件的的调用会更方便;第三,调度和管理,内核线程的调度和管理由操作系统内核完成,所以它们可以并发地运行在多个处理器上。
用户线程是在用户空间中创建和管理的线程,与内核线程相对应。用户线程是由应用程序或用户层库创建和调度的,不涉及操作系统内核的直接支持。用户线程的创建、调度和管理都是在用户空间中完成的。特点是相比内核线程,性能会更高,缺点就是需要用户自己调度。
这两个概念简单来说内核线程是操作系统自动去开启运行调用的线程,用户线程是用户主动开启,让操作系统去运行调用。
在python的实际操作中如何选择是使用多线程还是使用多进程呢,请看下面的代码:
多进程
import time
#from threading import Thread
from multiprocessing import Process
count = 0
def add():
global count
for i in range(10000000):
count = count + 1
if __name__ == '__main__':
start = time.time()
processes = []
for i in range(10):
p = Process(target=add)
processes.append(p)
for process in processes:
process.start()
for process in processes:
process.join()
end = time.time()
print(f"时间:{end - start}")
print(f"count:{count}")
在调用多进程库Process后对从1加到100000000的计算最终打印的时间是0.87665秒
多线程
import time
from threading import Thread
#from multiprocessing import Process
count = 0
def add():
global count
for i in range(10000000):
count = count + 1
if __name__ == '__main__':
start = time.time()
processes = []
for i in range(10):
p = Thread(target=add)
processes.append(p)
for process in processes:
process.start()
for process in processes:
process.join()
end = time.time()
print(f"时间:{end - start}")
print(f"count:{count}")
在调用多进程库Thread后对从1加到100000000的计算最终打印的时间是4.15973秒
两者之间存在巨大的效率差距
为什么会这样呢?
在Python中,多进程比多线程计算快的主要原因是Python的全局解释器锁(Global Interpreter Lock,GIL)。GIL是一种机制,它确保在任何给定的时间内,只有一个线程可以执行Python字节码。
由于GIL的存在,多线程在Python中无法实现真正的并行计算。虽然多个线程可以在不同的CPU核心上执行,但每个线程在执行Python代码时都需要获取GIL,这导致了多线程在执行CPU密集型任务时无法充分利用多核处理器的能力。
相比之下,多进程是通过创建多个独立的Python解释器来实现并行计算的。每个进程都有自己独立的解释器和GIL,它们可以在不受GIL限制的情况下同时执行计算任务,充分利用多核处理器的能力。
另外,多进程还具有更好的隔离性。每个进程拥有独立的内存空间,不同进程之间的数据不会相互影响,这可以避免并发访问共享数据时的竞态条件和锁竞争问题。
需要注意的是,对于IO密集型任务,多线程可能会比多进程更高效,因为GIL在IO操作时会释放,允许多个线程并发执行IO操作。
所以在Python关于计算方面的时候一般会用多进程,但是多线程也不是说没用了,只要不涉及极端,比如对数组进行排序,找出数组中的最大值和最小值这种的时候,多线程的效率和缓存占用率还是优于多进程的,所以要根据具体情况作出选择。