如何在Windows中创建线程安全的单例模式? [英] How can I create a thread-safe singleton pattern in Windows?

查看:219
本文介绍了如何在Windows中创建线程安全的单例模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里阅读了有关线程安全的单例模式:

I've been reading about thread-safe singleton patterns here:

http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B_.28using_pthreads.29

它在底部说,唯一安全的方法是使用pthread_once - 这是不可用的Windows。

And it says at the bottom that the only safe way is to use pthread_once - which isn't available on Windows.

只有保证线程安全初始化的方式?

Is that the only way of guaranteeing thread safe initialisation?

我已经读过这个线程的SO:

I've read this thread on SO:

a href =http://stackoverflow.com/questions/6915/thread-safe-lazy-contruction-of-a-singleton-in-c> http://stackoverflow.com/questions/6915/thread-safe -lazy-contruction-of-a-singleton-in-c

http://stackoverflow.com/questions/6915/thread-safe-lazy-contruction-of-a-singleton-in-c

似乎暗示了原子操作系统级别的交换和比较函数,我假设在Windows上是:

And seems to hint at an atomic OS level swap and compare function, which I assume on Windows is:

http:// msdn .microsoft.com / en-us / library / ms683568.aspx

这可以做我想要的吗?

编辑:我希望延迟初始化,并且只有一个类的实例。

I would like lazy initialisation and for there to only ever be one instance of the class.

网站提到使用全局内部的命名空间(和他描述单身作为一个反模式) - 它怎么会是一个反模式?

Someone on another site mentioned using a global inside a namespace (and he described a singleton as an anti-pattern) - how can it be an "anti-pattern"?

已接受答案:

我已接受

Accepted Answer:
I've accepted Josh's answer as I'm using Visual Studio 2008 - NB: For future readers, if you aren't using this compiler (or 2005) - Don't use the accepted answer!!

编辑
代码工作正常,除了return语句 - b $ b error C2440:'return':无法从'volatile Singleton *'转换为'Singleton *'。
我应该将返回值修改为volatile Singleton *?

修改:显然const_cast<挥发性限定词。再次感谢Josh。

Apparently const_cast<> will remove the volatile qualifier. Thanks again to Josh.

推荐答案

如果您使用Visual C ++ 2005/2008,可以使用双重锁定模式,因为 volatile variables表现为栅栏。这是实现延迟初始化单例的最有效的方法。

If you are are using Visual C++ 2005/2008 you can use the double checked locking pattern, since "volatile variables behave as fences". This is the most efficient way to implement a lazy-initialized singleton.

MSDN杂志:

Singleton* GetSingleton()
{
    volatile static Singleton* pSingleton = 0;

    if (pSingleton == NULL)
    {
        EnterCriticalSection(&cs);

        if (pSingleton == NULL)
        {
            try
            {
                pSingleton = new Singleton();
            }
            catch (...)
            {
                // Something went wrong.
            }
        }

        LeaveCriticalSection(&cs);
    }

    return const_cast<Singleton*>(pSingleton);
}

每当你需要访问单例时,只需调用GetSingleton第一次调用时,静态指针将被初始化。在初始化之后,NULL检查将阻止只读取指针的锁定。

Whenever you need access to the singleton, just call GetSingleton(). The first time it is called, the static pointer will be initialized. After it's initialized, the NULL check will prevent locking for just reading the pointer.

不要在任何编译器上使用,因为它不是便携式。标准不保证这将如何工作。 Visual C ++ 2005明确地增加了volatile的语义,使之成为可能。

DO NOT use this on just any compiler, as it's not portable. The standard makes no guarantees on how this will work. Visual C++ 2005 explicitly adds to the semantics of volatile to make this possible.

你必须声明和初始化代码中的CRITICAL SECTION 。但是初始化很便宜,所以延迟初始化通常不重要。

You'll have to declare and initialize the CRITICAL SECTION elsewhere in code. But that initialization is cheap, so lazy initialization is usually not important.

这篇关于如何在Windows中创建线程安全的单例模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆