积少成多

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  • 当析构函数遇到多线程,当一个对象能被多个线程同时看到,那么对象的销毁时机就变得模糊不清了,可能出现多种竞争条件race condition:
    • 在即将析构一个对象时,如何得知此刻是  否有别的线程正在执行该对象的成员函数
    • 如何保证在执行成员函数期间,对象不会在另一个线程被析构
    • 在调用某个对象的成员函数之前,如何得知这个对象还活着? 它的析构函数不会碰巧执行到一半?
    • 记住share_ptr的用法.
  • 线程安全:三个条件.  多个线程同时访问时,其表现出正确的行为;无论os如何调度这些线程,无论这些线程的执行顺序如何交织;调用端代码无须额外的同步或其他协调动作.    那么c++,标准库中的大多数class都不是线程安全的,包括std::string,vector,map,必须加深能够额外的锁才可以供多个线程同时访问.
  • MutexLock/MutexLockGuard,自己实现的类.   MutexLock,利用RAII收方封装互斥器的常见与销毁/临界区在windows上是struct CRITICAL_SECTION,是可重入的,而linux上的pthread_mutex_t默认是不可重入的. MutexLock一般是别的class的数据成员.;;;;;;;;MutexLockGuard封装临界区的进入和退出,即加锁和解锁.MutexLockGuard一般是栈上对象,作用域刚好等于临界区.
  • 怎么样分析线程安全呢? 每个对象有自己的mutex_,因此不同对象之间不构成锁争用.  mutex_ 成员是mutable的,意味着const成员函数如Counter::value也能直接使用non-const的mutex_.
class Counter : boost::noncopyable{
    public:
    Counter():value_(0){}
    int value() const;
    int getAndIncrease();
    private:
        int value_;
        mutable MutexLock mutex_;
};
int Counter::value() const{
    MutexLockGuard lock(mutex_);///lock的析构会晚育返回对象的构造
    
    return value_; 
    ///lock会在这里析构,作用域结束的时候,因此可以有效包括这个功效数据
}
int Counter::getAndIncrease(){
    MutexLockGuard lock(mutex_);
    int  ret  = value_++;///每个对象有自己的mutex_,因此不同对象之间不构成锁争用.
    return ret;
}

 

  • c++可能出现的内存有一下几个方面:
    1. 缓冲区溢出 buffer overrun
    2. 空悬指针/野指针
    3. 重复释放 double delete
    4. 内存泄露 memkory leak
    5. 不配对的new[]/delete
    6. 内存碎片 memory

        正确使用智能指针share_ptr/weak_ptr解决前面的5个问题,

    1. 缓冲区溢出,用std::vector<char>/std::string或自己编写buffer class管理缓冲区,自动记住缓冲区的长度,公国成员函数而不是裸指针来修改缓冲区.
    2. 空悬指针/野指针,使用share_ptr/weak_ptr
    3. 重复释放,利用scopted_ptr,只在对象析构的时候释放一次
    4. 内存泄露:利用scopted_ptr,利利用
  • 对象的创建,  要做到线程安全,唯一的要求就是在狗仔期间不要泄露this指针:
    • 不要在构造函数中注册任何回调
    • 也不要在构造函数中把this指针传递给跨线程的对象
    • 即便在构造函数最后一行也不行
posted on 2016-06-05 11:43  x7b5g  阅读(334)  评论(0编辑  收藏  举报