Python中具有多线程的多进程

Python中具有多线程的多进程,python,multithreading,multiprocessing,gil,Python,Multithreading,Multiprocessing,Gil,我听说过“如果你想从并行应用程序中获得最大的性能,你应该创建尽可能多的进程,就像你的计算机有CPU一样,并且在每个进程中--创建一些(多少?)线程” 这是真的吗 我写了一段代码来实现这个习惯用法: import multiprocessing, threading number_of_processes = multiprocessing.cpu_count() number_of_threads_in_process = 25 # some constant def one_thre

我听说过“如果你想从并行应用程序中获得最大的性能,你应该创建尽可能多的进程,就像你的计算机有CPU一样,并且在每个进程中--创建一些(多少?)线程”

这是真的吗

我写了一段代码来实现这个习惯用法:

import multiprocessing, threading

number_of_processes = multiprocessing.cpu_count()
number_of_threads_in_process = 25   # some constant


def one_thread():
    # very heavyweight function with lots of CPU/IO/network usage
    do_main_work()


def one_process():
    for _ in range(number_of_threads_in_process):
        t = threading.Thread(target=one_thread, args=())
        t.start()


for _ in range(number_of_processes):
    p = multiprocessing.Process(target=one_process, args=())
    p.start()
对吗?我的
主功能是否真的能并行运行,而不面临任何GIL问题

多谢各位

# very heavyweight function with lots of CPU/IO/network usage
大量的CPU将因为GIL而受损,因此您只能从多个进程中受益

IOnetwork(实际上网络也是一种IO)不会受到GIL的太大影响,因为lock被显式释放,并在IO操作完成后再次获得。中有用于此的宏定义:

Py_BEGIN_ALLOW_THREADS
... Do some blocking I/O operation ...
Py_END_ALLOW_THREADS
由于在包装代码时使用了GIL,性能仍然会受到影响,但使用多个线程仍然可以获得更好的性能


最后——这是一条通用规则——不仅仅适用于Python:线程/进程的最佳数量取决于程序实际执行的操作。通常,如果它大量使用CPU,那么如果进程数大于CPU核数,则几乎不会有性能提升。例如,Gentoo文档说编译器的最佳线程数是CPU内核+1。

这在很大程度上取决于您正在做什么

请记住,在CPython中,一次只能有一个线程执行Python字节码(因为GIL)。因此,对于CPython中的计算密集型问题,线程不会有多大帮助

分散可以并行完成的工作的一种方法是使用
多处理.Pool
。默认情况下,这不会使用CPU具有核心的更多进程。使用更多的进程主要是为了争夺资源(CPU、内存),而不是完成有用的工作

但是利用多个处理器需要你有工作要做!换句话说,如果问题不能被分割成更小的部分,这些部分可以单独或并行计算,那么许多CPU核心就没有多大用处

此外,并非所有问题都受到必须进行的计算量的限制

计算机的RAM比CPU慢得多。如果您正在处理的数据集比CPU的缓存大得多,则从RAM读取数据并将结果返回到RAM可能成为速度限制。这就是所谓的


如果您处理的数据远远超过了机器内存的容量,那么您的程序将从磁盘执行大量的读写操作。磁盘比RAM慢,比CPU慢,因此您的程序变得非常慢。

我认为每个进程使用的线程数太高。通常对于任何Intel处理器,每个进程的线程数都是2。内核数从2(Intel core i3)到6(Intel core i7)不等。因此,当所有进程都在运行时,最大线程数将为6*2=12。

每个进程中有25个线程,在它们之间,GIL仍然存在。