關於GIL的案例

2021-08-20 03:41:55 字數 2847 閱讀 6291

例1:

import threading

import time

def run(n):

print("task",n)

time.sleep(2)

print("task done=>",n)

start_time=time.time()

for i in range(5):

t=threading.thread(target=run,args=('t-%s'%i,))

t.start()

print('cost:',time.time()-start_time)

'''執行結果:

task t-0

task t-1

task t-2

task t-3

task t-4

cost: 0.0009999275207519531

task done=> t-3

task done=> t-1

task done=> t-2

task done=> t-0

task done=> t-4

'''

例2:

importthreading

importtime

num=0

defrun(n):

print("task",n)

globalnum

num+=1

time.sleep(2)

print("task done=>",n,'num=',num)

start_time=time.time()

foriinrange(5):

t=threading.thread(target=run,args=('t-%s'%i,))

t.start()

print('cost:',time.time()-start_time)

'''執行結果:task t-0task t-1task t-2task t-3task t-4cost: 0.0019998550415039062task done=> t-0 num= 5task done=> t-1 num= 5task done=> t-3 num= 5task done=> t-2 num= 5task done=> t-4 num= 5'''

分析上面兩個例子的區別:

由例1輸出可以分析得到:

先生成的執行緒不一定先執行結束

例2引入了全域性變數num,並且每次執行後會將num值輸出。但是為什麼每次的輸出結果都是num=5呢,而不是依次遞增?

實驗3:

importthreading

importtime

num=0

defrun(n):

print("task",n)

globalnum

num+=1

time.sleep(2)

print("task done=>",n,'num=',num)

start_time=time.time()

foriinrange(5):

t=threading.thread(target=run,args=('t-%s'%i,))

ifi==3:

time.sleep(3)

t.start()

print('cost:',time.time()-start_time)

'''執行結果:task t-0task t-1task t-2task done=> t-2 num= 3task done=> t-0 num= 3task done=> t-1 num= 3task t-3task t-4cost: 3.003000020980835task done=> t-3 num= 5task done=> t-4 num= 5'''

例3當i==3時,手動暫停3秒,可以看到輸出的結果符合預期,前三秒一樣,後兩秒一樣。

但是為什麼是這樣,python3中做了哪些關於鎖的設定,沒有深究。

GIL問題的理解

簡單說 執行緒的鎖機制與cpu的鎖 gil 粒度不一樣,gil並不能保證執行緒安全 單個位元組碼操作 原子操作 是執行緒安全的,非原子操作是多位元組碼操作 所以我理解的gil只是使一些簡單的原子操作變成了執行緒安全的 而非那些原子操作的過程仍然 需要我們自己使用鎖機制進行同步 gil保證的是位元組碼...

python 關於IF的使用案例

import math import random 練習1,判斷是否潤年 def fan year int input 你問我猜 if year 400 0 or year 4 0 and year 100 0 print 您輸入的年份 d 是潤年 year else print 您輸入的年份 d ...

11 1 多執行緒的GIL

gil global interpreter lock 基於cpython寫的 gil使得python在多核cpu上也只能執行乙個程序 所謂多核多個程序再跑是乙個假象,他是來回切換的,問題 gil 在同乙個程序直到結束才會釋放嗎?total 0 defadd global total for i i...