线程安全单例模式示例

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

  • 注意问题:

    • 多线程安全
    • 资源申请时机
    • 性能问题
  • 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;
}

2017-08-09更新 增加mutex资源管理

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

class MutexLock {
public:
    MutexLock() {
        pthread_mutex_init(&_mutex, NULL);
    }

    ~MutexLock() {
        pthread_mutex_destroy(&_mutex);
    }

    void lock() {
        pthread_mutex_lock(&_mutex);
    }

    void unlock() {
        pthread_mutex_unlock(&_mutex);
    }

private:
    pthread_mutex_t _mutex;
};

class MutexLockGuard {
public:
    explicit MutexLockGuard(MutexLock& mutex_lock) :
        _mutex_lock(mutex_lock)
    {
        _mutex_lock.lock();
    }

    ~MutexLockGuard() {
        _mutex_lock.unlock();
    }

private:
    MutexLock& _mutex_lock;
};

class MySing {
public:
    static MySing* create_instance() {
        if (_my_sing == NULL) {
            // lock
            MutexLockGuard lock(_mutex_lock);
            _mutex_lock.lock();
            if (_my_sing == NULL) {
                _my_sing = new MySing();
            }
            // unlock
        }
        cout << "create done" << endl;
        return _my_sing;
    }

    void say_hi() {
        cout << "hi" << endl;
    }

protected:
    MySing() {}

private:
    MySing(const MySing&);
    MySing& operator=(const MySing&);

private:
    static MutexLock _mutex_lock;
    static MySing* _my_sing;
};

MutexLock MySing::_mutex_lock;
MySing* MySing::_my_sing = NULL;

int main() {
    MySing::create_instance();
    //MySing::create_instance()->say_hi();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值