self
.
_lock
.
acquire
(
)
while
self
.
_connections
>=
self
.
_max
:
print
(
"waiting..."
)
self
.
_lock
.
wait
(
)
try
:
con
=
self
.
_cache
.
pop
(
0
)
except
:
con
=
Obj
(
)
self
.
_connections
+=
1
finally
:
self
.
_lock
.
release
(
)
return
direct
(
self
,
con
)
def
cache
(
self
,
conn
)
:
try
:
self
.
_lock
.
acquire
(
)
self
.
_cache
.
append
(
conn
)
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
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
)
1-1 PersistentDB
1、此模块好处是能保证线程安全,为每一个线程建立一个连接,所以线程之间的链接是不共享的。
每个线程每次获取都是同一个链接,当线程完成或杀死的时候,链接就关闭了。
2、有稳定个数的线程用PersistentDB
3、使用多线程时没有返回所有
在工作中难免会使用数据库,为了能够高效并发访问数据库,数据库
连接池
必不可少,由于本站copy模式盛行,导致数据库
连接池
被错误使用,遇到错误甚至追求能跑通就行。本文就数据库链接池的实际使用场景来说明如何应用数据库
连接池
。在部署机器学习模型时采用的是flask框架,模型预测本身是一个很快的事情,无奈有太多的特征需要通过接口(或者是ots,mysql等)获取,导致响应时效性降低。为了能很好的
实现
并发性,提升QPS,采用gunicorn进行多进程,异步处理方案。此时单个进程只有一个数据库链接,就会导致异步执行的线程
一 DBUtils的认识首先管理数据库
连接池
的包是 DBUtils,为高频度并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放,最常用的两个外部接口是PersistentDB 和 PooledDB,前者提供了单个线程专用的数据库
连接池
,后者则是进程内所有线程共享的数据库
连接池
。二 DBUtils 简介DBUtils是一套
Python
数据库
连接池
包,并允许对非线程安全的数据库接口进行...
from DBUtils.PooledDB import PooledDB
dbpool = PooledDB(creator=MySQLdb, maxusage=1000,host='host',user='root', passwd='pwd',db='test')
conn = dbpool.connect...