python多線程
實(shí)驗(yàn):
- 開啟兩個(gè)線程
- 一個(gè)線程sleep 4s 死循環(huán)打印
- 另外一個(gè)線程sleep 1s 死循環(huán)打印
結(jié)果:會(huì)正常的交替運(yùn)行
結(jié)論:一個(gè)線程被阻塞的時(shí)候歧蕉,CPU會(huì)被釋放缎讼,然后另外一個(gè)線程被執(zhí)行。。
使用python為例子
參考資料:
[http://zhuoqiang.me/python-thread-gil-and-ctypes.html](http://zhuoqiang.me/python-thread-gil-and-ctypes.html)
所有Thread的PID都與主程序相同,而每個(gè)Process都有一個(gè)不同的PID要
單線程
使用如下的代碼:
#!coding=utf8
"""
使用多核
"""
import sys
sys.path.append('../../')
if __name__ == "__main__":
print("start run here")
while True:
a = 4 / 34.0
print('end run here')
開始運(yùn)行前
使用
python expmultiprocess.py
開始運(yùn)行后
可以看出,占滿一個(gè)核心的所有資源了。
主線程外再開啟一個(gè)線程
可以看出:
- 有兩個(gè)進(jìn)程號(hào)循头。PID是不一樣的。
- 所有的CPU并沒有占満
因?yàn)镚IL的原因:
- 單進(jìn)程單線程可以占用并占滿一個(gè)核心炎疆。
- 單進(jìn)程多線程可以占用多核心但無法占滿卡骂,只會(huì)分時(shí)復(fù)用。
GIL全局解釋器鎖
參考資料:http://zhuoqiang.me/python-thread-gil-and-ctypes.html
GIL 的全程為 Global Interpreter Lock 形入,意即全局解釋器鎖全跨。
在 Python 語言的主流實(shí)現(xiàn) CPython 中,GIL 是一個(gè)貨真價(jià)實(shí)的全局線程鎖亿遂,在解釋器解釋執(zhí)行任何 Python 代碼時(shí)浓若,都需要先獲得這把鎖才行,在遇到 I/O 操作時(shí)會(huì)釋放這把鎖蛇数。如果是純計(jì)算的程序挪钓,沒有 I/O 操作,解釋器會(huì)每隔 100 次操作就釋放這把鎖耳舅,讓別的線程有機(jī)會(huì)執(zhí)行碌上,這個(gè)次數(shù)可以通過sys.setcheckinterval。
所以雖然 CPython 的線程庫直接封裝操作系統(tǒng)的原生線程,但 CPython 進(jìn)程做為一個(gè)整體馏予,同一時(shí)間只會(huì)有一個(gè)獲得了 GIL 的線程在跑蔓纠,其它的線程都處于等待狀態(tài)等著 GIL 的釋放。這也就解釋了我們上面的實(shí)驗(yàn)結(jié)果:雖然有兩個(gè)死循環(huán)的線程吗蚌,而且有兩個(gè)物理 CPU 內(nèi)核,但因?yàn)?GIL 的限制纯出,兩個(gè)線程只是做著分時(shí)切換蚯妇,總的 CPU 占用率還略低于 50%。
以java為例子
Java的多線程是完全可以把多個(gè)核心跑滿的暂筝。
package com.data;
public class ThreadDemo extends Thread {
public ThreadDemo() {
}
public void run() {
while (true) {
continue;
}
}
public static void main(String[] args) {
try {
ThreadDemo h1 = new ThreadDemo();
h1.start();
ThreadDemo h2 = new ThreadDemo();
h2.start();
ThreadDemo h3 = new ThreadDemo();
h3.start();
h1.join();
h2.join();
h3.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
里面開啟了三個(gè)線程箩言,然后CPU三個(gè)核心都跑滿了。
使用pyspark運(yùn)行
Python可以通過一些專門的數(shù)據(jù)處理框架來實(shí)現(xiàn)高效利用CPU焕襟,直接所有的核心都利用起來了陨收。不用自己再去寫并行計(jì)算的內(nèi)容結(jié)構(gòu)了。