ITPub博客

首页 > 区块链 > 区块链 > hash游戏竞猜系统开发方案丨哈希HASH游戏竞猜系统开发方案/(源码部署)

hash游戏竞猜系统开发方案丨哈希HASH游戏竞猜系统开发方案/(源码部署)

原创 区块链 作者:Tg_StPv888 时间:2023-03-28 10:55:46 0 删除 编辑

使用模块其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。

因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

如果我们真的想要一个单例类,可以考虑这样做:class Singleton(object):(開发)找(铭籽)

    def foo(self):

        pass

singleton = Singleton()

将上面的代码保存在文件 mysingleton.py 中,要使用时,直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象

from mysingleton import singleton

使用装饰器

def Singleton(cls):

    _instance = {}

    def _singleton(*args, **kargs):

        if cls not in _instance:

            _instance[cls] = cls(*args, **kargs)

        return _instance[cls]

    return _singleton

@Singleton

class A(object):

    a = 1

    def __init__(self, x=0):

        self.x = x

a1 = A(2)

a2 = A(3)

使用类

class Singleton(object):

    def __init__(self):

        pass

    @classmethod

    def instance(cls, *args, **kwargs):

        if not hasattr(Singleton, "_instance"):

            Singleton._instance = Singleton(*args, **kwargs)

        return Singleton._instance

一般情况,大家以为这样就完成了单例模式,但是当使用多线程时会存在问题:

class Singleton(object):

    def __init__(self):

        pass

    @classmethod

    def instance(cls, *args, **kwargs):

        if not hasattr(Singleton, "_instance"):

            Singleton._instance = Singleton(*args, **kwargs)

        return Singleton._instance

import threading

def task(arg):

    obj = Singleton.instance()

    print(obj)

for i in range(10):

    t = threading.Thread(target=task,args=[i,])

    t.start()

程序执行后,打印结果如下:

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

<__main__.Singleton object at 0x02C933D0>

看起来也没有问题,那是因为执行速度过快,如果在 __init__ 方法中有一些 IO 操作,就会发现问题了。

下面我们通过 time.sleep 模拟,我们在上面 __init__ 方法中加入以下代码:

def __init__(self):

    import time

    time.sleep(1)

重新执行程序后,结果如下:

<__main__.Singleton object at 0x034A3410>

<__main__.Singleton object at 0x034BB990>

<__main__.Singleton object at 0x034BB910>

<__main__.Singleton object at 0x034ADED0>

<__main__.Singleton object at 0x034E6BD0>

<__main__.Singleton object at 0x034E6C10>

<__main__.Singleton object at 0x034E6B90>

<__main__.Singleton object at 0x034BBA30>

<__main__.Singleton object at 0x034F6B90>

<__main__.Singleton object at 0x034E6A90>

问题出现了!按照以上方式创建的单例,无法支持多线程。

解决办法:加锁!未加锁部分并发执行,加锁部分串行执行,速度降低,但是保证了数据安全。

import time

import threading

class Singleton(object):

    _instance_lock = threading.Lock()

    def __init__(self):

        time.sleep(1)

    @classmethod

    def instance(cls, *args, **kwargs):

        with Singleton._instance_lock:

            if not hasattr(Singleton, "_instance"):

                Singleton._instance = Singleton(*args, **kwargs)

        return Singleton._instance

def task(arg):

    obj = Singleton.instance()

    print(obj)

    

for i in range(10):

    t = threading.Thread(target=task,args=[i,])

    t.start()

time.sleep(20)

obj = Singleton.instance()

print(obj)

打印结果如下:

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

<__main__.Singleton object at 0x02D6B110>

这样就差不多了,但是还是有一点小问题,就是当程序执行时,执行了 time.sleep(20) 后,下面实例化对象时,此时已经是单例模式了。

原创声明,本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70016646/viewspace-2942052/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
专业区块项目开发团队:18028578624微電

注册时间:2022-04-13

  • 博文量
    158
  • 访问量
    95693