为什么这个C ++静态单例从不停止? [英] Why does this C++ static singleton never stop?

查看:110
本文介绍了为什么这个C ++静态单例从不停止?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++中实现了一个单例(静态版本)。我知道关于这种模式和潜在的线程安全问题的所有争议,但我很好奇为什么这个确切的实现不会停止。程序从不退出,在结束时仍处于死锁状态。



singleton.h:

  #pragma once 
#include< thread>
#include< atomic>

类Singleton
{
public:
static Singleton& getInstance();

private:
std :: thread mThread;
std :: atomic_bool mRun;

Singleton();
〜Singleton();
void threadFoo();
};

singleton.cpp

  #includesingleton.h

Singleton& Singleton :: getInstance()
{
static Singleton实例;
return instance;
}

Singleton :: Singleton()
{
mRun.store(true);
mThread = std :: thread(& Singleton :: threadFoo,this);
}

Singleton ::〜Singleton()
{
mRun.store(false);

if(mThread.joinable())
mThread.join();
}

void Singleton :: threadFoo()
{
while(mRun)
{
}
}

main.cpp

  #includesingleton.h

int main()
{
Singleton :: getInstance();
return 0;
}

我已经知道:


$ b b

  • 线程终止

  • 主线程卡在连接中

  • 如果我使构造函数public并在main()中创建一个Singleton的实例,它将正确终止。



使用Visual Studio感谢您的建议。

解决方案

确定谢谢大家的提示。显然这个模式实现导致VC ++的死锁。



在做了一些进一步的研究后,我发现这个实现基于C ++ 11力学在VC ++。 p>

singleton.h

  #pragma once 
#include< ; thread>
#include< atomic>
#include< memory>
#include< mutex>


类Singleton
{
public:
static Singleton& getInstance();
virtual〜Singleton();

private:
static std :: unique_ptr< Singleton>实例;
static std :: once_flag mOnceFlag;
std :: thread mThread;
std :: atomic_bool mRun;

Singleton();

void threadFoo();
};

singleton.cpp

  #includesingleton.h

std :: unique_ptr< Singleton> Singleton :: mInstance = nullptr;
std :: once_flag Singleton :: mOnceFlag;


Singleton& Singleton :: getInstance()
{
std :: call_once(mOnceFlag,[] {m​​Instance.reset(new Singleton);});
return * mInstance.get();
}


Singleton :: Singleton()
{
mRun.store(true);
mThread = std :: thread(& Singleton :: threadFoo,this);
}

Singleton ::〜Singleton()
{
mRun.store(false);

if(mThread.joinable())
mThread.join();
}

void Singleton :: threadFoo()
{
while(mRun.load())
{
}
}

UPDATE


$ b b

似乎Microsoft已经知道这个问题。在VC ++论坛中,名为dlafleur的用户报告了此帖:
https:/ /connect.microsoft.com/VisualStudio/feedback/details/747145


i have implemented a singleton (static version) in C++. I know all the controversy about this pattern and potential thread-safety issues, but i am curious why this exact implementation won't halt. The program never quits, it remains in a deadlock state at the end.

singleton.h:

#pragma once
#include <thread>
#include <atomic>

class Singleton
{
public:
    static Singleton& getInstance();

private:
    std::thread mThread;
    std::atomic_bool mRun;

    Singleton();
    ~Singleton();
    void threadFoo();
};

singleton.cpp

#include "singleton.h"

Singleton& Singleton::getInstance()
{
    static Singleton instance;
    return instance;
} 

Singleton::Singleton()
{
    mRun.store(true);
    mThread = std::thread(&Singleton::threadFoo, this);
}

Singleton::~Singleton()
{
    mRun.store(false);

    if(mThread.joinable())
        mThread.join();
}

void Singleton::threadFoo()
{
    while(mRun)
    {
    }
}

main.cpp

#include "singleton.h"

int main()
{
    Singleton::getInstance();
    return 0;
}

What I already know:

  • the thread terminates
  • the main thread is stuck in the join
  • it has something to do with the static, if i make the constructor public and create an instance of Singleton in main() it will correctly terminate.

Using Visual Studio 2012. Thanks for your advice.

解决方案

Ok thank you all for your hints. Apparently this pattern implementation results in a deadlock on VC++.

After doing some further research i found this implementation based on C++11 mechanics which is working in VC++.

singleton.h

#pragma once
#include <thread>
#include <atomic>
#include <memory>
#include <mutex>


class Singleton
{
public:
    static Singleton& getInstance();
    virtual ~Singleton();

private:
    static std::unique_ptr<Singleton> mInstance;
    static std::once_flag mOnceFlag;
    std::thread mThread;
    std::atomic_bool mRun;

    Singleton();

    void threadFoo();
};

singleton.cpp

#include "singleton.h"

std::unique_ptr<Singleton> Singleton::mInstance = nullptr;
std::once_flag Singleton::mOnceFlag;


Singleton& Singleton::getInstance()
{
    std::call_once(mOnceFlag, [] { mInstance.reset(new Singleton); });
    return *mInstance.get();
}


Singleton::Singleton()
{
    mRun.store(true);
    mThread = std::thread(&Singleton::threadFoo, this);
}

Singleton::~Singleton()
{ 
    mRun.store(false);

    if(mThread.joinable())
        mThread.join();
}

void Singleton::threadFoo()
{
    while(mRun.load())
    {
    }
}

UPDATE

It looks like Microsoft is aware of this issue. In the VC++ forums a user named "dlafleur" reported this post: https://connect.microsoft.com/VisualStudio/feedback/details/747145

这篇关于为什么这个C ++静态单例从不停止?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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