面試頭條的時候:Python的多線程有什麼特色?當時直接答不會。。java
結論:Python的多線程是假的,不能有效的利用多核。python
先看幾個例子,面試
1. python的多線程多線程
#coding=utf-8 from multiprocessing import Pool from threading import Thread from multiprocessing import Process def loop(): while True: pass if __name__ == '__main__': for i in range(3): t = Thread(target=loop) t.start() while True: pass
個人電腦是4核,因此我開了4個線程,看一下CPU資源佔有率:ide
咱們發現CPU利用率並無佔滿,大體至關於單核水平。而若是咱們變成進程呢?oop
2. python的多進程#coding=utf-8 from multiprocessing import Pool from threading import Thread from multiprocessing import Process def loop(): while True: pass if __name__ == '__main__': for i in range(3): t = Process(target=loop) t.start() while True: pass
結果直接飆到了100%,說明進程是能夠利用多核的!spa
咱們再用Java/C重寫一下,開啓多線程。線程
3. java的多線程設計
package com.darrenchan.thread; public class TestThread { public static void main(String[] args) { for (int i = 0; i < 3; i++) { new Thread(new Runnable() { @Override public void run() { while (true) { } } }).start(); } while(true){ } } }
因而可知,Java中的多線程是能夠利用多核的,這是真正的多線程!而Python中的多線程只能利用單核,這是假的多線程!code
爲何會這樣?
GIL鎖,而後,每執行100條字節碼,解釋器就自動釋放GIL鎖,讓別的線程有機會執行。這個GIL全局鎖實際上把全部線程的執行代碼都給上了鎖,因此,多線程在Python中只能交替執行,即便100個線程跑在100核CPU上,也只能用到1個核。
GIL是Python解釋器設計的歷史遺留問題,一般咱們用的解釋器是官方實現的CPython,要真正利用多核,除非重寫一個不帶GIL的解釋器。
怎麼解決呢?
若是必定要經過多線程利用多核,那隻能經過C擴展來實現,例如Numpy底層就是C++實現的。不過這樣就失去了Python簡單易用的特色
另外一方面,Python雖然不能利用多線程實現多核任務,但能夠經過多進程實現多核任務。多個Python進程有各自獨立的GIL鎖,互不影響。
參考連接:
1. https://www.liaoxuefeng.com/wiki/1016959663602400/1017629247922688