在 Python 多线程下,每个线程执行之前都需要获取 GIL 后才能执行线程代码中的代码,直到遇到 IO 阻塞或达到线程的最长执行时间后释放 GIL,等待下一次调度.而每次释放 GIL 锁,多个线程会进行锁竞争,切换线程,会造成资源损耗.这就是为什么即便在多核 CPU ,Python 的多线程效率可能并不高.
对于 CPU 密集型代码来说,多线程之间存在锁竞争,切换线程,会造成不必要的资源损耗,所以 Python 的多线程对 CPU 密集型代码并不友好.因此对于多核场景,推荐使用多进程,每个进程中的单个线程有独立的 GIL,互不干扰,这样就可以真正意义上的并行执行.
defincrement_n_times(n): global total for i in range(n): total += 1
defsafe_increment_n_times(n): global total for i in range(n): lock.acquire() total += 1 lock.release()
defincrement_in_x_threads(x, func, n): threads = [threading.Thread(target=func, args=(n,)) for i in range(x)] global total total = 0 begin = time.time() for thread in threads: thread.start() for thread in threads: thread.join() print('finished in {}s.\ntotal: {}\nexpected: {}\ndifference: {} ({} %)' .format(time.time()-begin, total, n*x, n*x-total, 100-total/n/x*100))