c++ - C++中的单例多线程代码

标签 c++ multithreading concurrency singleton

我对 C++ 中的单例和多线程编程有疑问 下面您可以看到带有名为 shared 的变量的 Singleton 类的示例代码。

我创建了 1000 个线程来修改 (+​​1) 我的 Singleton 全局实例的那个变量。 shared 的最终值为 1000,但我希望此值低于 1000,因为我没有保护此变量以实现并发。

代码真的是线程安全的,因为类是 Singleton 还是只是碰巧值是 1000 但它完全可以小于 1000?

#include <iostream>
using namespace std;

class Singleton {
private:
    Singleton() {shared = 0;};
    static Singleton * _instance;
    int shared;

public:
    static Singleton* Instance();
    void increaseShared () { shared++; };
    int getSharedValue () { return shared; };
};

// Global static pointer used to ensure a single instance of the class.
Singleton* Singleton::_instance = NULL;

Singleton * Singleton::Instance() {
    if (!_instance) { 
        _instance = new Singleton;
    }

    return _instance;
}

void * myThreadCode (void * param) {
    Singleton * theInstance;
    theInstance = Singleton::Instance();
    theInstance->increaseShared();

    return NULL;
}

int main(int argc, const char * argv[]) {
    pthread_t threads[1000];
    Singleton * theInstance = Singleton::Instance();

    for (int i=0; i<1000; i++) {
        pthread_create(&threads[i], NULL, &myThreadCode, NULL);
    }

    cout << "The shared value is: " << theInstance->getSharedValue() << endl;

    return 0;
}

最佳答案

Is the code really thread safe because the class is Singleton or it just happened to be lucky and the value is 1000 but it can perfectly be less than 1000?

你很幸运......

实际上,您所观察到的最有可能的问题与这样一个事实有关,即在您的特定机器上增加单例值所花费的时间少于操作系统增加单例值所花费的时间分配资源以启动单个 pthread。因此,您永远不会遇到两个线程争用单例未 protected 资源的情况。

更好的测试是首先启动所有 的 pthreads,让它们阻塞在障碍或条件变量上,然后在障碍的所有条件变量上执行单例增量满足“事件”线程的条件……到那时,您更有可能看到非原子操作(如增量操作)发生的各种数据争用。

关于c++ - C++中的单例多线程代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11514913/

相关文章:

java - 锁定文件并读取它

ios - UIImageView 延迟绘制

c++ - final 在虚函数上的奇怪行为

c++ - 分期付款 - float 错误 C2296

C++多维数组

c# - Java 和 C# 线程处理数据同步的方式有何不同?

Java并发实践Listing10.6 synchronized

c++ - boost :任意分布的 vector

c# - 获取 sleep 线程在 C# 中唤醒的剩余时间

.net - 如何获取调度程序的 TaskScheduler?