C++中的Singleton多线程代码

Jor*_*rge 2 c++ concurrency singleton multithreading

我对使用C++中的Singleton和多线程编程有疑问之后您可以看到Singleton类的示例代码,其中包含名为shared的变量.

我创建了1000个线程来修改(+1)我的Singleton全局实例的变量.共享的最终值是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;
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*son 5

代码是否真的是线程安全的,因为类是Singleton或它恰好是幸运的,值是1000但它可以完全小于1000?

你真是幸运...

实际上,您观察到的最可能的问题与以下事实有关:在特定计算机上增加单例值所花费的时间少于操作系统分配资源所需的时间发起一个单独的pthread.因此,您永远不会遇到两个线程争用单例的未受保护资源的情况.

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