天天看點

Python3學習(二十四):python中的線程之semaphore信号量

semaphore是一個内置的計數器

  • 每當調用acquire()時,内置計數器-1
  • 每當調用release()時,内置計數器+1

計數器不能小于0,當計數器為0時,acquire()将阻塞線程直到其他線程調用release()。

來看下面的代碼:

import time
import threading

def foo():
    time.sleep(2)   #程式休息2秒
    print("ok",time.ctime())

for i in range(20):
    t1=threading.Thread(target=foo,args=()) #執行個體化一個線程
    t1.start()  #啟動線程
           

執行結果:

ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
ok Tue Jul 18 20:05:58 2017
           

可以看到,程式會在很短的時間内生成20個線程來列印一句話。

如果在主機執行IO密集型任務的時候再執行這種類型的程式時,計算機就有很大可能會當機。

這時候就可以為這段程式添加一個計數器功能,來限制一個時間點内的線程數量。

代碼如下:

import time
import threading

s1=threading.Semaphore(5)   #添加一個計數器

def foo():
    s1.acquire()    #計數器獲得鎖
    time.sleep(2)   #程式休眠2秒
    print("ok",time.ctime())
    s1.release()    #計數器釋放鎖


for i in range(20):
    t1=threading.Thread(target=foo,args=()) #建立線程
    t1.start()  #啟動線程
           

執行結果:

ok Tue Jul 18 20:04:38 2017
ok Tue Jul 18 20:04:38 2017
ok Tue Jul 18 20:04:38 2017
ok Tue Jul 18 20:04:38 2017
ok Tue Jul 18 20:04:38 2017
ok Tue Jul 18 20:04:40 2017
ok Tue Jul 18 20:04:40 2017
ok Tue Jul 18 20:04:40 2017
ok Tue Jul 18 20:04:40 2017
ok Tue Jul 18 20:04:40 2017
ok Tue Jul 18 20:04:42 2017
ok Tue Jul 18 20:04:42 2017
ok Tue Jul 18 20:04:42 2017
ok Tue Jul 18 20:04:42 2017
ok Tue Jul 18 20:04:42 2017
ok Tue Jul 18 20:04:44 2017
ok Tue Jul 18 20:04:44 2017
ok Tue Jul 18 20:04:44 2017
ok Tue Jul 18 20:04:44 2017
ok Tue Jul 18 20:04:44 2017