以下实现,使用延迟初始化Singleton(Meyers'Seingleton)线程安全吗?
static Singleton& instance()
{
static Singleton s;
return s;
}
Run Code Online (Sandbox Code Playgroud)
如果没有,为什么以及如何使其线程安全?
我有一个foo()由互斥锁保护的函数,m它被定义为一个局部静态变量foo().我想知道foo()在bar具有静态存储持续时间的对象的析构函数中调用是否安全:
// foo.h
void foo();
// foo.cpp
#include "foo.h"
#include <mutex>
void foo() {
static std::mutex m;
std::lock_guard<std::mutex> lock(m);
// ...
}
// bar.h
struct Bar { ~Bar(); };
extern Bar bar;
// bar.cpp
#include "bar.h"
#include "foo.h"
Bar::~Bar() { foo(); }
Bar bar;
// main.cpp
int main() {
Bar bar;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果std::mutex是可以轻易破坏的,这应该是安全的,因为bar之前会被破坏m.在GCC 5.4,Ubuntu 16.04上,调用std::is_trivially_destructible<std::mutex>::value返回true,所以至少在这个编译器中似乎没问题.任何明确的答案?
相关:关于静态和全局变量的 Google …
我有一堆线程,每个线程都需要一个线程安全的随机数。由于在我的真实程序中,线程是重复生成和连接的,所以我不想创建random_device并且mt19937每次进入一个调用相同函数的新并行区域时,所以我将它们设置为静态:
#include <iostream>
#include <random>
#include <omp.h>
void test(void) {
static std::random_device rd;
static std::mt19937 rng(rd());
static std::uniform_int_distribution<int> uni(1, 1000);
int x = uni(rng);
# pragma omp critical
std::cout << "thread " << omp_get_thread_num() << " | x = " << x << std::endl;
}
int main() {
# pragma omp parallel num_threads(4)
test();
}
Run Code Online (Sandbox Code Playgroud)
我无法放置它们,threadprivate因为错误 C3057:当前不支持“threadprivate”符号的动态初始化。一些消息来源说random_device和mt19937是线程安全的,但我还没有找到任何可以证明这一点的文档。
我试图在使用单例实例的不同线程上运行print()和print(char ch)方法.
错误C3867:'Singleton :: print':函数调用缺少参数列表; 使用'&Singleton :: print'创建指向成员的指针
错误C3867:'Singleton :: print':函数调用缺少参数列表; 使用'&Singleton :: print'创建指向成员的指针
错误C2661:'std :: thread :: thread':没有重载函数需要2个参数
class Singleton
{
private:
Singleton()
{}
static Singleton* singletonInstance;
public:
static Singleton* getSingletonInstance();
void print()
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
for (int i = 0; i < 100000; i++)
{
cout<<i<<endl;
}
}
void print(char ch)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
for (int i = 0; i < 100000; i++)
{
cout<<ch<<" "<<i<<endl;
}
}
};
Singleton* Singleton::singletonInstance = nullptr;
Singleton* Singleton::getSingletonInstance()
{
if(!singletonInstance) …Run Code Online (Sandbox Code Playgroud) 所以我写了一个简单的单例类.当我创建一个对象时,会调用构造函数,但是当它超出范围时,它的析构函数(释放对象)似乎不会被调用.
#include <iostream>
using namespace std;
class Singleton {
public:
static Singleton &getInstance( )
{
if (instance == nullptr) {
cout << "Creating instance.\n";
instance = new Singleton();
}
return *instance;
}
static void destroyInstance( )
{
if (instance != nullptr) {
cout << "Destroying instance.\n";
delete instance;
instance = nullptr;
}
}
~Singleton( )
{
if (instance != nullptr) {
cout << "Destroying instance.\n";
delete instance;
instance = nullptr;
}
}
private:
Singleton( ) { }
static Singleton *instance; …Run Code Online (Sandbox Code Playgroud) 这里有两个单例,为什么第一个更可取,因为两者都只会实例化相应类的一个实例:
第一的:
class SharedPointerSingleton {
public:
static std::shared_ptr< SharedPointerSingleton> getSingleton(
{
if( s_pSingleton== 0 ) s_pSingleton = std::shared_ptr< SharedPointerSingleton>(new SharedPointerSingleton());
return s_pSingleton;
}
private:
SharedPointerSingleton(){};
static std::shared_ptr< SharedPointerSingleton> s_pSingleton;
};
Run Code Online (Sandbox Code Playgroud)
第二:
class PointerSingleton {
public:
static PointerSingleton * getSingleton(
{
if( pSingleton== 0 ) pSingleton = new PointerSingleton ());
return pSingleton;
}
private:
PointerSingleton (){};
static PointerSingleton * pSingleton;
};
Run Code Online (Sandbox Code Playgroud) 我正在编写一个线程安全的单例类,如下所示.以下实现确保只创建了一个类的实例.我的用例是我在多线程环境中使用此实例,其中每个线程可以getInstance()使用该实例调用并执行一些工作.我的问题是如何确保在特定时间只有一个线程正在使用该实例,以防止在多个线程同时尝试使用单个实例时可能发生的竞争条件.
class Singleton {
Singleton() {}
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
public:
static Singleton& getInstance() {
static Singleton s;
return s;
}
};
Run Code Online (Sandbox Code Playgroud) 在这些条件下,我编写了下一个Singleton类:
1 - 我想要一个且只有一个类的实例存在并且可以从整个游戏引擎访问.
2 - Singleton被密集使用(每帧数千次)所以我不想写一个额外的GetInstance()函数,我试图避免任何额外的函数调用性能
3 - 一种可能性是让GetInstance()像内联一样这个 :
inline Singleton* Singleton::GetInstance()
{
static Singleton * singleton = new Singleton();
return singleton;
}
Run Code Online (Sandbox Code Playgroud)
但这会引起一个引用问题,每次调用时都会有一个对单例的新引用,用于修复用c ++编写的内容:
class Singleton{
private:
static Singleton* singleton;
Singleton(){}
public:
static inline Singleton* GetInstance() // now can be inlined !
{
return singleton;
}
static void Init()
{
// ofc i have to check first if this function
// is active only once
if(singleton != nullptr)
{
delete singleton;
}
singleton = new Singleton();
} …Run Code Online (Sandbox Code Playgroud)