文档章节

python 单例模式实现多线程共享连接池

鼎铭
 鼎铭
发布于 2017/09/02 23:42
字数 605
阅读 170
收藏 0

     我们经常使用数据库连接池,但那是有时候有些库并没有实现线程安全的连接池,这个时候,该如何自己封装?多进程和多线程甚至协程模式下,如何控制数据库连接数量或者是socket连接数。这个问题很有意义。

该文章后续仍在不断的更新修改中, 请移步到原文地址http://dmwan.cc

    首先,多进程,通常的做法是每个进程实例化一个连接池,为什么不共享一个池,因为多进程和多线程同步的开销不一样,一般三方库都不会支持,但是redis 的库可以,他有些细节不一样。然后多线程共享,只需要将连接放到一个线程安全的容器,比如list 或者queue中。注意多线程和多进程的queue实现方式完全不一样,多线程是使用的mmap。

    下面看看一个demo:

import multiprocessing
import threading
import os



def singleton(cls, *args, **kw):
    instances = {}#
    print "instance is",id(instances)
    def _singleton():
        #key = str(cls) + str(os.getpid())
        key = str(cls)
        if key not in instances:
            instances[key] = cls(*args, **kw)
        return instances[key]

    return _singleton
    print "instance has been free"

@singleton
class DB(object):
    def __init__(self):
        self.rabbitmq_pool = self.init_rabbitmq_pool()

    def init_rabbitmq_pool(self):
        pool = 1#为了简化
        return pool


#DB = singleton(DB)


def process1():
    print "proc 1 "
    db1 = DB()
    print "db1 is ", id(db1)


def process2():
    print "proc 2 "
    db2 = DB()
    print "db2 is", id(db2)

if __name__=="__main__":
    # print "multiproce "
    # pro1 = multiprocessing.Process(target=process1)
    # pro2 = multiprocessing.Process(target=process2)
    # pro1.start()
    # pro2.start()
    # pro1.join()
    # pro2.join()

    print "print thread"
    pro1 = threading.Thread(target=process1)
    pro2 = threading.Thread(target=process2)
    pro1.start()
    pro2.start()
    pro1.join()
    pro2.join()

这部分代码是简化了自己封装的连接池的代码, 主要观察线程单例是否生效,然后那个instance为什么线程能够共享一个连接池。

下面是打印结果:

instance is 140442806348048
print thread
proc 1 
db1 is  140442806366352proc 2 

db2 is 140442806366352

    看到结果,其实很多问题就知道答案了,使用装饰器后, 整个代码段加载的时候,装饰器就已经开始执行,这里的instances 是不会释放的,实际上代码初始化的时候就执行了DB = singleton(DB) ,相当于是 这个闭包是全局变量,又因为dict本身线程安全。所以每次线程用这闭包的时候,获取连接对象都是线程安全的。

    这里的单例对多进程是不会生效的。   

© 著作权归作者所有

共有 人打赏支持
鼎铭
粉丝 26
博文 67
码字总数 40583
作品 0
东城
程序员
Python学习:19.Python设计模式-单例模式

一、单例模式存在的意义   在这里的单例就是只有一个实例(这里的实例就像在面向对象的时候,创建了一个对象也可以说创建了一个实例),只用一个实例进行程序设计,首先我们可以了解一下什...

BD-ld-2017
07/31
0
0
《 Head First 》学习笔记:策略模式 (python实现)

学习<head first>,书中是用java 来实现,我用python比较多,所以在这里记下 用python实现的方法 。 书中策略模式的定义 : 策略模式 : 策略模式定义了算法族,分别封装起来,让它们之间可以...

Jbryan
2013/06/13
0
0
python 与设计模式 ——工厂与单例

python 与设计模式 源码地址:[http://git.oschina.net/duoduo3_69/python_design_pattern][1] git checkout v001(这个版本与此篇博客相符) zarkpy里面运用了很多设计模式,以前一直很费解p...

duoduo3_69
2013/11/27
0
0
Python新式类 new init 单例模式与作用域(四)

1 新式类与旧式类 新式类拥有经典类的全部特性之外,还有一些新的特性,比如 发生变化,新增了静态方法,python3目前都采用新式类,新式类是广度优先,旧式类是深度优先 (2)类的方法 静态方法 类方...

善良小郎君
06/18
0
0
大数据分析技术:Python面试之理解__new__和__init__的区别

很多同学都以为Python中的init是构造方法,但其实不然,Python中真正的构造方法是new。init和new有什么区别?本文就来探讨一下。 我们先来看一下init的用法 上面的代码会输出如下的结果 那么...

加米谷大数据
07/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

docker中安装了RabbitMQ后无法访问其Web管理页面

在官网找了"$ docker run -d --hostname my-rabbit --name some-rabbit -p 8080:15672 rabbitmq:3-management"这条安装命令,在docker上安装了RabbitMQ,,结果输入http://localhost:8080并不......

钟然千落
31分钟前
0
0
spring-cloud | 分布式session共享

写在前面的话 各位小伙伴,你们有福了,这一节不仅教大家怎么实现分布式session的问题,还用kotlin开发,喜欢kotlin的小伙伴是不是很开心! 以前在写Android的时候,就对客户端请求有一定的认...

冯文议
50分钟前
0
0
c语言之内存分配笔记

先看一个数组: short array[5] = {1,2} // 这儿定义的一个int类型的数组,数组第1和第2个元素值是1和2.其余后面默认会给值为0; 或者 short array[] = {1,2};//这儿数组第1和第2个元素,数组...

DannyCoder
今天
4
0
Shell | linux安装包不用选择Y/N的方法

apt-get install -y packageOR echo "y" | sudo apt-get install package

云迹
今天
2
0
Hadoop的大数据生态圈

基于Hadoop的大数据的产品圈 大数据产品的一句话概括 Apache Hadoop: 是Apache开源组织的一个分布式计算开源框架,提供了一个分布式文件系统子项目(HDFS)和支持MapReduce分布式计算的软件架...

zimingforever
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部