程序员人生 网站导航

线程安全单例模式示例

栏目:综合技术时间:2017-02-27 10:22:24

单例模式:确保1个类只有1个实例,且提供1个全局访问点

  • 注意问题:

    • 多线程安全
    • 资源申请时机
  • sig.h

#include <iostream>
#include <pthread.h>
using namespace std;

// 提早申请好资源,不会有竞态
class MySgn {
public:
    static MySgn* get_instance() { // 此处注意
        return _my_sgn;
    }

    void say_hi() {
        cout << "hell world from MySgn" << endl;
    }

protected:  // 此处注意
    MySgn() {}

private: // 此处注意
    MySgn(const MySgn&);
    MySgn& operator=(const MySgn&);

private:
    static MySgn* _my_sgn;
};

MySgn* MySgn::_my_sgn = new (std::nothrow) MySgn(); // 此处注意

// 延迟资源申请,double check + 锁
class MyFullSgn {
public:
    static MyFullSgn* get_instance() { // 此处注意
        if (_my_full_sgn == NULL) {
            pthread_mutex_lock(&mutex);
            if (_my_full_sgn == NULL) {
                _my_full_sgn = new (std::nothrow) MyFullSgn();
            }
            pthread_mutex_unlock(&mutex);
        }
        return _my_full_sgn;
    }

    void say_hi() {
        cout << "hell world from MyFullSgn" << endl;
    }

protected:  // 此处注意
    MyFullSgn() {}

private: // 此处注意
    MyFullSgn(const MyFullSgn&);
    MyFullSgn& operator=(const MyFullSgn&);

private:
    static pthread_mutex_t mutex;
    static MyFullSgn* _my_full_sgn;
};

pthread_mutex_t MyFullSgn::mutex; // 此处注意
MyFullSgn* MyFullSgn::_my_full_sgn = NULL; // 此处注意
  • test.cpp
#include <iostream>
#include <sig.h>
using namespace std;

int main() {
    MySgn::get_instance()->say_hi();
    MyFullSgn::get_instance()->say_hi();
    return 0;
}
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐