最近闲来无事,重新温固了一遍连接池(DB)的实现原理,以下为连接池实现的简易代码:
#coding:utf8
import time
import threading
class Pool:
def __init__(self,max):
self._max = max
self._connections = 0
self._lock = threading.Condition()
self._cache = []
def get(self):
try:
#请求锁
self._lock.acquire()
while self._connections>=self._max:
print("waiting...")
self._lock.wait()
try:
#优先从缓存池中获取
con = self._cache.pop(0)
except:
#如果缓存池没有对象,则重新创建
con = Obj()
#使用数累计+1
self._connections+= 1
finally:
self._lock.release()
return direct(self,con)
def cache(self,conn):
try:
self._lock.acquire()
#把使用完毕的连接添加到缓存池中
self._cache.append(conn)
#使用数-1
self._connections-= 1
self._lock.notify()
finally:
self._lock.release()
def __del__(self):
try:
#释放的时候,将连接关闭
self._lock.acquire()
while self._cache:
con = self._cache.pop(0)
con.close()
finally:
self._lock.release()
class direct:
def __init__(self,pool,con):
self._pool = pool
self._con = con
def close(self):
#将连接添加到缓存池
self._pool.cache(self._con)
def __del__(self):
#释放的时候调用
self.close()
def __getattr__(self, name):
if self._con:
return getattr(self._con, name)
else:
raise InvalidConnection
class Obj:
def __init__(self):
print("init")
def close(self):
print("close")
def __del__(self):
self.close()
_LOCK_ = threading.RLock() # 锁
_POOL_ = None
#根据ID连接库
def connect():
global _POOL_
if _LOCK_.acquire(1):
try:
#如果没有初始化 用默认池
if not _POOL_:
_POOL_=Pool(3)
return _POOL_.get()
finally:
_LOCK_.release()
def test(i):
print("---begin--:%s"%i)
d=connect()
time.sleep(10)
print("---end---:%s"%i)
if __name__ == "__main__":
for i in range(6):
t = threading.Thread(target=test,args=(i,))
t.setDaemon(True)
t.start()
time.sleep(1)
time.sleep(60)