Last active
August 29, 2015 14:08
-
-
Save fbigun/595f022ab6736dfeedb5 to your computer and use it in GitHub Desktop.
Revisions
-
fbigun revised this gist
Oct 27, 2014 . 2 changed files with 0 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,3 @@ 在***Python***中如果对象定义了`__del__`方法的话,在对象的引用记数为0时会自动调用`__del__`方法 (很象c++中的析构函数),但如果A对象引用B对象,B对象又引用A对象,就形成循环引用,此时A,B对象 引用次数都为1。python就无法正常调用`__del__`方法,原计划在`__del__`方法里释放的资源自然也就无 File renamed without changes. -
fbigun revised this gist
Oct 27, 2014 . 2 changed files with 11 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,2 +0,0 @@ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,11 @@ 在***Python***中如果对象定义了`__del__`方法的话,在对象的引用记数为0时会自动调用`__del__`方法 (很象c++中的析构函数),但如果A对象引用B对象,B对象又引用A对象,就形成循环引用,此时A,B对象 引用次数都为1。python就无法正常调用`__del__`方法,原计划在`__del__`方法里释放的资源自然也就无 法释放。 一个连接池拥有多个连接,而每个连接又拥有这个连接池的实例(一个叫pool的属性)。这样就产生了刚刚 说的哪个问题。我想到的办法就是在每次从池中获取连接的时候将连接的pool设置为当前实例,然后在归 还这个连接的时候再将其设置为***None***,并且要在这个连接对象的`__del__`方法中将pool属性设置为 ***None***。具体看代码吧。(目前只实现了SQLite3的) -
fbigun created this gist
Oct 27, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,121 @@ ''' Created on 2009-4-17 @author: phyeas ''' import time from queue import Queue class PoolException(Exception): pass class Pool(object): '''一个数据库连接池''' def __init__(self, maxActive=5, maxWait=None, init_size=0, db_type="SQLite3", **config): self.__freeConns = Queue(maxActive) self.maxWait = maxWait self.db_type = db_type self.config = config if init_size > maxActive: init_size = maxActive for i in range(init_size): self.free(self._create_conn()) def __del__(self): print("__del__ Pool..") self.release() def release(self): '''释放资源,关闭池中的所有连接''' print("release Pool..") while self.__freeConns and not self.__freeConns.empty(): con = self.get() con.release() self.__freeConns = None def _create_conn(self): '''创建连接 ''' if self.db_type in dbcs: return dbcs[self.db_type](**self.config); def get(self, timeout=None): '''获取一个连接 @param timeout:超时时间 ''' if timeout is None: timeout = self.maxWait conn = None if self.__freeConns.empty():#如果容器是空的,直接创建一个连接 conn = self._create_conn() else: conn = self.__freeConns.get(timeout=timeout) conn.pool = self return conn def free(self, conn): '''将一个连接放回池中 @param conn: 连接对象 ''' conn.pool = None if(self.__freeConns.full()):#如果当前连接池已满,直接关闭连接 conn.release() return self.__freeConns.put_nowait(conn) from abc import ABCMeta, abstractmethod class PoolingConnection(object, metaclass=ABCMeta): def __init__(self, **config): self.conn = None self.config = config self.pool = None def __del__(self): self.release() def __enter__(self): pass def __exit__(self, exc_type, exc_value, traceback): self.close() def release(self): print("release PoolingConnection..") if(self.conn is not None): self.conn.close() self.conn = None self.pool = None def close(self): if self.pool is None: raise PoolException("连接已关闭") self.pool.free(self) def __getattr__(self, val): if self.conn is None and self.pool is not None: self.conn = self._create_conn(**self.config) if self.conn is None: raise PoolException("无法创建数据库连接 或连接已关闭") return getattr(self.conn, val) @abstractmethod def _create_conn(self, **config): pass class SQLit3PoolConnection(PoolingConnection): def _create_conn(self, **config): import sqlite3 return sqlite3.connect(**config) dbcs = {"SQLite3":SQLit3PoolConnection} pool = Pool(database="F:\\test\\a") def test(): conn = pool.get() with conn: for a in conn.execute("SELECT * FROM A"): print(a) if __name__ == "__main__": test() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,2 @@ 在***Python***中如果对象定义了`__del__`方法的话,在对象的引用记数为0时会自动调用`__del__`方法(很象c++中的析构函数),但如果A对象引用B对象,B对象又引用A对象,就形成循环引用,此时A,B对象引用次数都为1。python就无法正常调用`__del__`方法,原计划在`__del__`方法里释放的资源自然也就无法释放。 一个连接池拥有多个连接,而每个连接又拥有这个连接池的实例(一个叫pool的属性)。这样就产生了刚刚说的哪个问题。我想到的办法就是在每次从池中获取连接的时候将连接的pool设置为当前实例,然后在归还这个连接的时候再将其设置为***None***,并且要在这个连接对象的`__del__`方法中将pool属性设置为***None***。具体看代码吧。(目前只实现了SQLite3的)