Odd*_*ing 19 python design-patterns data-structures
我需要一个对象池,而不是自己实现它,我想我会四处寻找一个现成的和经过测试的Python库.
我发现很多其他人在寻找,但没有得到很多直接的答案,所以我把它带到了Stack Overflow.
在我的例子中,我有大量的线程(使用threading模块),需要偶尔调用一个基于SOAP的远程服务器.他们每个人都可以建立自己与服务器的连接,但设置套接字并完成身份验证过程是很昂贵的(它受到服务器的限制),所以我想共享一个连接池,只在需要时创建更多连接.
如果要汇总的项目是工作子过程,我可能已经选择了multiprocessing.pool,但它们不是.如果它们是工作线程,我可能选择了这个实现,但它们不是.
如果它们是MySQL连接,我可能选择了pysqlpool,但它们不是.同样,SQLAlchemy Pool已经出局了.
如果有一个线程,使用可变数量的连接/对象,我会考虑这个实现,但我需要它是线程安全的.
我知道我可以很快再次实现它,但鉴于有很多人在寻找它,我认为Stack Overflow上的规范答案会很好.
Ale*_*lli 25
在我的描述中,在我看来,你需要的是一个连接池,而不是对象.为了简单的线程安全,只需将可重用连接保留在Queue.Queue实例中,然后调用它pool.当一个线程实例化一个连接包装对象时,该对象通过pool.get()它自动获取它的连接(如果当前没有可用的连接则自动将它排队等待,并在连接准备就绪时将其出列); 当对象使用其连接完成时,它会将其放回池中pool.put.
除了Queue.Queue已经提供的内容之外,这里几乎没有普遍要求的通用功能,没有任何提供它的模块是众所周知的或流行的并不奇怪 - 当它有大约6行功能代码时很难使模块普及总之(例如,调用用户提供的连接工厂以提前填充队列或准时填充到某个最大数量 - 通常不是一个很大的附加值)."厚胶",从标准库模块厚厚地包裹底层功能而没有实质性的附加值,毕竟是体系结构减去;-).
我有一个类似的问题,我必须说 Queue.Queue 非常好,但是有一个拼图的缺失部分。以下类有助于确保获取的对象返回到池中。包括示例。
我允许通过 2 种方式使用此类,即使用关键字或使用析构函数封装对象。with 关键字是首选,但如果您由于某种原因不能/不想使用它(最常见的是需要来自多个队列的多个对象),至少您有一个选择。如果您选择使用该方法,则有关不会调用析构函数的标准免责声明适用。
希望这可以帮助与 OP 和我自己有相同问题的人。
class qObj():
_q = None
o = None
def __init__(self, dQ, autoGet = False):
self._q = dQ
if autoGet == True:
self.o = self._q.get()
def __enter__(self):
if self.o == None:
self.o = self._q.get()
return self.o
else:
return self.o
def __exit__(self, type, value, traceback):
if self.o != None:
self._q.put(self.o)
self.o = None
def __del__(self):
if self.o != None:
self._q.put(self.o)
self.o = None
if __name__ == "__main__":
import Queue
def testObj(Q):
someObj = qObj(Q, True)
print 'Inside func: {0}'.format(someObj.o)
aQ = Queue.Queue()
aQ.put("yam")
with qObj(aQ) as obj:
print "Inside with: {0}".format(obj)
print 'Outside with: {0}'.format(aQ.get())
aQ.put("sam")
testObj(aQ)
print 'Outside func: {0}'.format(aQ.get())
'''
Expected Output:
Inside with: yam
Outside with: yam
Inside func: sam
Outside func: sam
'''
Run Code Online (Sandbox Code Playgroud)