import threading
import logging
import time
FORMAT = '%(threadName)s %(thread)d %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)
def worker(s:threading.Semaphore):
logging.info('in sub thread')
logging.info(s.acquire()) # 獲取信號量,計數(shù)器 -1
logging.info('sub thread over')
s = threading.Semaphore(3) # 創(chuàng)建3個信號量計數(shù)器
logging.info(s.acquire())
print(s._value) # 看看現(xiàn)在信號量的內(nèi)的數(shù)值是多少
logging.info(s.acquire())
print(s._value)
logging.info(s.acquire())
print(s._value)
threading.Thread(target=worker, args=(s, )).start()
time.sleep(2)
logging.info(s.acquire(False)) # 不阻塞,若獲取不到信號量,則為False
logging.info(s.acquire(timeout=10)) # 設(shè)置超時時間,等待超時時間過了還未獲取到信號,返回值為False
# 釋放
logging.info('released')
s.release() # 釋放信號量,計數(shù)器i + 1
import threading
import logging
import random
FORMAT = '%(threadName)s %(thread)d %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)
class Conn:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
class Pool:
def __init__(self, count:int):
self.count = count
self.pool = [ self._connect('conn-{}'.format(x)) for x in range(self.count)]
def _connect(self, conn_name):
return Conn(conn_name)
def get_conn(self):
conn = self.pool.pop()
return conn
def return_conn(self, conn:Conn):
self.pool.append(conn)
pool = Pool(3)
def worker(pool:Pool):
conn = pool.get_conn()
logging.info(conn)
threading.Event().wait(random.randint(1,4))
pool.return_conn(conn)
for i in range(6):
threading.Thread(target=worker, name='worker-{}'.format(i), args=(pool,)).start()
import threading
import logging
import random
FORMAT = '%(threadName)s %(thread)d %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)
class Conn:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
class Pool:
def __init__(self, count:int):
self.count = count
self.pool = [ self._connect('conn-{}'.format(x)) for x in range(self.count)]
self.semahore = threading.Semaphore(count)
def _connect(self, conn_name):
return Conn(conn_name)
def get_conn(self):
self.semahore.acquire()
conn = self.pool.pop()
return conn
def return_conn(self, conn:Conn):
self.pool.append(conn)
self.semahore.release()
pool = Pool(3)
def worker(pool:Pool):
conn = pool.get_conn()
logging.info(conn)
threading.Event().wait(random.randint(1,4))
pool.return_conn(conn)
for i in range(6):
threading.Thread(target=worker, name='worker-{}'.format(i), args=(pool,)).start()
當我們使用semaphore的時候,如果還未acquire,就release了,會產(chǎn)生什么問題?
會產(chǎn)生是的信號量的值+1,超出了原本設(shè)置semaphore的初始值,下面的例子說明了這個問題
創(chuàng)新互聯(lián)是一家專業(yè)的成都網(wǎng)站建設(shè)公司,我們專注網(wǎng)站制作、成都網(wǎng)站設(shè)計、網(wǎng)絡(luò)營銷、企業(yè)網(wǎng)站建設(shè),買鏈接,一元廣告為企業(yè)客戶提供一站式建站解決方案,能帶給客戶新的互聯(lián)網(wǎng)理念。從網(wǎng)站結(jié)構(gòu)的規(guī)劃UI設(shè)計到用戶體驗提高,創(chuàng)新互聯(lián)力求做到盡善盡美。
import threading
import logging
FORMAT = '%(threadName)s %(thread)d %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)
sema = threading.Semaphore(3)
logging.warning(sema.__dict__)
for _ in range(3):
sema.acquire()
logging.warning('-----')
logging.warning(sema.__dict__)
for _ in range(4):
sema.release()
logging.warning(sema.__dict__)
for _ in range(3):
sema.acquire()
logging.warning('--------')
logging.warning(sema.__dict__)
sema.acquire()
logging.warning('======')
logging.warning(sema.__dict__)
所以這個這樣的問題,可以使用BoundedSemaphore類來實現(xiàn)有界的信號量,若relase超出了初始值的范圍,會拋出ValueError異常