关于C++ 单例模式的double-check的疑问。

最近在学习单例模式,在了解频繁加锁会造成资源的浪费的前提下,通常做法时使用
双重检查的机制来解决资源浪费。于是我做了以下测试:

#include <unistd.h>
#include <pthread.h>
#include <iostream>
#include <vector>
#include <sys/time.h>
using namespace std;

pthread_mutex_t lo;
class Singleton
{
public:
    static Singleton * p_instance;
    static Singleton * GetInstance();
private:
    Singleton(){cout<<"Contructor running"<<endl;}
};
Singleton * Singleton::p_instance=NULL;
Singleton * Singleton::GetInstance()
{
    if(p_instance==NULL)
    {
        pthread_mutex_lock(&lo);
        if(p_instance==NULL)
        p_instance=new Singleton();
        pthread_mutex_unlock(&lo);
    }
    pthread_mutex_unlock(&lo);

    return p_instance;
}

void * fun(void *)
{
    Singleton::GetInstance();
}

int main()
{
    //cout<<&lo<<endl;
    pthread_mutex_init(&lo,NULL);
    vector<pthread_t *> thread_pool;
    for(int i=0;i<10000000;i++)
    {
        pthread_t * pth = new pthread_t;        
        thread_pool.push_back(pth);

    }

    //calculate time duration
    struct timeval t1,t2;
    double duration=0;
    gettimeofday(&t1,NULL);
    for(int i=0;i<thread_pool.size();i++)
    {
        pthread_create(thread_pool[i],NULL,fun,NULL);
    }
    for(int i=0;i<thread_pool.size();i++)
    pthread_join(*thread_pool[i],NULL);
    gettimeofday(&t2,NULL);
    duration = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec)/1000000.0;
    cout<<duration<<endl;
    return 0;

} 

结果在ubuntu18.04中测试耗时:14.907s

然后我将程序中的,第一个判空去掉,就像这样:

Singleton * Singleton::GetInstance()
{
    //if(p_instance==NULL)
    //{
        pthread_mutex_lock(&lo);
        if(p_instance==NULL)
        p_instance=new Singleton();
       // pthread_mutex_unlock(&lo);
    //}
    pthread_mutex_unlock(&lo);

    return p_instance;
}

同样地,进行了多次返回的结果是:

Contructor running
18.1153
me@ubuntu:~/Desktop/pocesstet$ ./app 
Contructor running
14.9578
me@ubuntu:~/Desktop/pocesstet$ ./app 
Contructor running
14.8444
me@ubuntu:~/Desktop/pocesstet$ ./app 
Contructor running
14.3856

时间时间甚至比使用双重检查(double check)的效果要好?这是为什么?
是我哪里理解错了吗?先谢谢各位了!

1个回答

时间开销都在线程创建上了,你的测试代码没有反应你单例本身的性能开销

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问