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 ) 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...