相关疑难解决方法(0)

C++中单例的线程安全延迟构造

有没有办法在C++中实现单例对象:

  1. 懒惰地以线程安全的方式构造(两个线程可能同时是单例的第一个用户 - 它应该仍然只构造一次).
  2. 不依赖于事先构造的静态变量(因此单例对象在构造静态变量期间本身是安全的).

(我不太了解我的C++,但是在执行任何代码之前初始化积分和常量静态变量的情况(即,甚至在执行静态构造函数之前 - 它们的值可能已在程序中"初始化")如果是这样的话 - 也许这可以被利用来实现单例互斥体 - 这反过来可以用来保护真正的单例的创建......)


很好,现在我似乎有几个好的答案(羞耻我不能标记2或3作为答案).似乎有两个广泛的解决方案:

  1. 使用POD静态变量的静态初始化(而不是动态初始化),并使用内置原子指令实现我自己的互斥锁.这是我在问题中暗示的那种解决方案,我相信我已经知道了.
  2. 使用其他库函数,如pthread_onceboost :: call_once.这些我当然不知道 - 并且非常感谢所发布的答案.

c++ singleton construction multithreading lazy-initialization

36
推荐指数
5
解决办法
2万
查看次数

如何在Windows中创建线程安全的单例模式?

我一直在阅读有关线程安全的单例模式:

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

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

这是保证线程安全初始化的唯一方法吗?

我在SO上读过这个帖子:

C++中单例的线程安全延迟构造

并且似乎暗示了原子操作系统级别的交换和比较功能,我在Windows上假设:

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

这可以做我想要的吗?

编辑:我想懒惰的初始化,因为只有一个类的实例.

另一个网站上有人提到在命名空间中使用全局(并且他将单例描述为反模式) - 它如何成为"反模式"?

一般承认的答案:
我已经接受了Josh的回答,因为我正在使用Visual Studio 2008 - 注意:对于未来的读者,如果您不使用此编译器(或2005) - 请勿使用接受的答案!

编辑: 除了return语句之外代码工作正常 - 我收到错误:错误C2440:'return':无法从'volatile Singleton*'转换为'Singleton*'.我应该将返回值修改为易失性Singleton*吗?

编辑:显然const_cast <>将删除volatile限定符.再次感谢Josh.

c++ windows singleton

16
推荐指数
2
解决办法
2万
查看次数

本地静态的线程安全初始化:MSVC

可能重复:
VC2010是静态init线程安全吗?

我知道gcc和llvm-clang发出代码以线程安全的方式初始化本地静态变量(这允许通过在函数中包装全局静态来逃避静态顺序初始化失败).

然而,这篇msdn博客文章是我在这些情况下可以找到的关于vcc行为的最佳文档,并且声称静态初始化不能是线程安全的,因为本地静态的初始化可以递归地调用相同的作用域.

我不买这个论点 - 如果初始化者依赖于它自己的结果,那显然是编程错误.

因此,鉴于本文来自2004年,gcc和clang可以做到这一点,并且当前的msvc文档是不明确的(声明'分配'到本地静态不是线程安全的,但仅此而已):

在MSVC中,本地静态的初始化现在是线程安全的吗?

如果没有,为什么不呢,因为gcc显然可以这样做,但程序员很难在之后加入.

c++ thread-safety visual-c++

7
推荐指数
1
解决办法
1510
查看次数

解决MSVC问题

我如何在MSVC中取消名称?gcc中有abi :: __ cxa_demangle函数.在MSDN中我找到了UnDecorateSymbolName:

http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms681400%28v=vs.85%29.aspx

不幸的是,这个功能甚至不能解开这样的符号:

#include <Windows.h>
#include <DbgHelp.h>

#include <cstdlib>
#include <iostream>
#include <typeinfo>

int main()
{
    SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);

    if (!SymInitialize(GetCurrentProcess(), NULL, TRUE))
    {
        std::cout << "SymInitialize returned error: " << GetLastError() << '\n';
        return EXIT_FAILURE;
    }

    class Foo {};
    Foo instance;

    const char* decorated_name = typeid(instance).name();
    char undecorated_name[1024];
    if (!UnDecorateSymbolName(decorated_name, undecorated_name, sizeof(undecorated_name) / sizeof(*undecorated_name), UNDNAME_COMPLETE))
    {
        std::cout << "UnDecorateSymbolName returned error: " << GetLastError() << '\n';
        return EXIT_FAILURE;
    }

    std::cout << "Decorated name: " << decorated_name …
Run Code Online (Sandbox Code Playgroud)

c++ winapi

7
推荐指数
3
解决办法
8849
查看次数

退出 glutFullScreen()

我不明白为什么当我按“f”时它进入全屏但不退出全屏。在这个方法的开头我已经设置了bool fullscreen = false;

这是我的切换代码:

case 'f': //toggle screenmode
    if(!fullscreen){
        glutFullScreen();
        fullscreen = true;
    } else if(fullscreen){
        glutReshapeWindow(1200, 900);
        glutPositionWindow(0,0);
        fullscreen = false;
    }
    break;
Run Code Online (Sandbox Code Playgroud)

c++ opengl glut

4
推荐指数
1
解决办法
8713
查看次数