全局解释器锁

由于 Global Interpreter Lock, Python 多线程性能通常会受到影响。简而言之,即使你可以在 Python 程序中拥有多个线程,但无论 CPU 数量多少,任何时候只能有一个字节码指令并行执行。

因此,在外部事件(如网络访问)阻止操作的情况下,多线程可能非常有效:

import threading
import time

def process():
    time.sleep(2)

start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))

start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print("Four runs took %.2fs" % (time.time() - start))

# Out: One run took 2.00s
# Out: Four runs took 2.00s

请注意,即使每个 process 执行 2 秒钟,这四个进程一起能够有效地并行运行,总共需要 2 秒。

但是,在 Python 代码中进行密集计算(例如大量计算)的情况下,多线程不会带来太多改进,甚至可能比并行运行更慢:

import threading
import time

def somefunc(i):
    return i * i

def otherfunc(m, i):
    return m + i

def process():
    for j in range(100):
        result = 0
        for i in range(100000):
            result = otherfunc(result, somefunc(i))

start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))

start = time.time()
threads = [threading.Thread(target=process) for _ in range(4)]
for t in threads:
    t.start()
for t in threads:
    t.join()
print("Four runs took %.2fs" % (time.time() - start))

# Out: One run took 2.05s
# Out: Four runs took 14.42s

在后一种情况下,多处理可以是有效的,因为多个进程当然可以同时执行多个指令:

import multiprocessing
import time

def somefunc(i):
    return i * i

def otherfunc(m, i):
    return m + i

def process():
    for j in range(100):
        result = 0
        for i in range(100000):
            result = otherfunc(result, somefunc(i))

start = time.time()
process()
print("One run took %.2fs" % (time.time() - start))

start = time.time()
processes = [multiprocessing.Process(target=process) for _ in range(4)]
for p in processes:
    p.start()
for p in processes:
    p.join()
print("Four runs took %.2fs" % (time.time() - start))

# Out: One run took 2.07s
# Out: Four runs took 2.30s