python 併發編程 多線程 GIL全局解釋器鎖基本概念

 

 

首先須要明確的一點是GIL並非Python的特性,它是在實現Python解析器(CPython)時所引入的一個概念。html

就比如C++是一套語言(語法)標準,可是能夠用不一樣的編譯器來編譯成可執行代碼。python

>有名的編譯器例如GCC,INTEL C++,Visual C++等。Python也同樣,一樣一段代碼能夠經過CPython,PyPy,Psyco等不一樣的Python執行環境來執行。linux

像其中的JPython就沒有GIL。然而由於CPython是大部分環境下默認的Python執行環境。因此在不少人的概念裏CPython就是Python,也就想固然的把GIL歸結爲Python語言的缺陷。因此這裏要先明確一點:GIL並非Python的特性,Python徹底能夠不依賴於GILwindows

只有CPython 有GIL全局解釋器鎖安全

 

二 GIL介紹

GIL本質就是一把互斥鎖,既然是互斥鎖,全部互斥鎖的本質都同樣,都是將併發運行變成串行,以此來控制同一時間內共享數據只能被一個任務所修改,進而保證數據安全。多線程

能夠確定的一點是:保護不一樣的數據的安全,就應該加不一樣的鎖。併發

 

執行python程序默認會生成一個進程 這個進程就是這個python解釋器程序函數

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import time
import os

print os.getpid()
time.sleep(1000)

 

[root@salt-server-192 ~]# python create_process.py 
1343

 

#在windows下查看
tasklist |findstr python

#在linux下下查看
ps -aux |grep python

 

 

在一個python的進程內,不只有這個程序的的主線程或者由該主線程開啓的其餘線程,還有解釋器開啓的垃圾回收等解釋器級別的線程,總之,全部線程都運行在這一個進程內ui

 

 

一、全部數據都是共享的,這其中,代碼做爲一種數據也是被全部線程共享的(test.py的全部代碼以及Cpython解釋器的全部代碼)
例如:test.py定義一個函數work,在進程內全部線程都能訪問到work的代碼,因而咱們能夠開啓三個線程而後target都指向該代碼,能訪問到意味着就是能夠執行。spa

二、全部線程的任務,都須要將任務的代碼當作參數傳給解釋器的代碼去執行,即全部的線程要想運行本身的任務,首先須要解決的是可以訪問到解釋器的代碼。

 

接上:

若是多個線程的target=work,那麼執行流程是

多個線程先訪問到解釋器的代碼,即拿到執行權限,而後將target的代碼交給解釋器的代碼去執行

 

參考python執行程序 三部曲文章 >>

 

 1.每起一個進程,在內存空間都會默認生成一個主線程

線程的代碼 taget參數 指向python代碼 。而後把python代碼,當作參數傳給解釋器的代碼去執行,即全部的線程要想運行本身的任務,首先須要解決的是可以訪問到解釋器的代碼。

圖片上的參數就是python代碼

 

2.進程內能夠開好多個線程

CPython裏面有一個垃圾回收機制 也是執行解釋器代碼,因此在進程內,內存空間會有一個垃圾回收線程

垃圾回收線程運行的是python解釋器代碼

 

由於進程內有4個線程,垃圾回收線程和其餘線程會同時執行,垃圾回收線程有可能和其餘線程工做衝突,致使數據不安全,

因此要控制 這些線程一個個運行 須要在CPython解釋器里加鎖

 

解釋器的代碼是全部線程共享的,因此垃圾回收線程也可能訪問到解釋器的代碼而去執行,這就致使了一個問題:對於同一個數據100,可能線程1執行x=100的同時,而垃圾回收執行的是回收100的操做,解決這種問題沒有什麼高明的方法,就是加鎖處理,以下圖的GIL,保證python解釋器同一時間只能執行一個任務的代碼

 

 

加了互斥鎖每一個線程要運行,每一個線程搶着加鎖, 一次執行 只能加鎖require() 一次  再加鎖require() 一次就變成阻塞狀態 要等到釋放release() 以後 再加鎖require(),

同一時間只能有一個線程搶到鎖,其餘線程都要等待

 

1.GIL全局解釋器鎖本質就是互斥鎖,加了GIL全局解釋器鎖 同時運行的多個線程,變成一個一個運行 ,效率低了, 但保證數據安全

2.只有Cpython解釋器纔有GIL ,有了互斥鎖,對CPython 解釋器來講 每啓動一個進程 這個進程內的多個線程 同一時間只能有一個在運行

 

3.也就是說python多線程不能用多核優點,在CPython 想用多核只能用多進程 單核只適合多線程

4.垃圾回收機制是否一直存在?

CPython的垃圾回收機制 定時銷燬 定時啓動的

相關文章
相關標籤/搜索