Linux多线程服务端编程笔记,陈硕Linux多线程服务端编程读书笔记 —— 第一章 线程安全的对象生命周期管理...

muduo书第一章的思维导图(新窗口打开可以看大图)

20200208190047540704.png

线程安全的对象析构和回调(使用shared_ptr和weak_ptr)

注释是英文的(工地英语…)

StockFactory.h

// in multi-thread environment, there maybe a race condition

// an object's destruction is difficult to handle for complex cases

// a good news is that a smart pointer named "shared_ptr" provides ability to release the resources automatically

#ifndef MUDUO_STOCKFACOTRY_H

#define MUDUO_STOCKFACOTRY_H

#include "Mutex.h"

#include

#include

#include

#include

class Stock

{

public:

Stock(const std::string &key);

std::string

Key() const;

private:

std::string key_;

};

class StockFactory1 : public boost::noncopyable

{

public:

std::shared_ptr get(const std::string &key);

private:

mutable MutexLock mutex_;

std::map<:string std::shared_ptr>> stocks_;

};

class StockFactory2 : public boost::noncopyable

{

public:

std::shared_ptr get(const std::string &key);

private:

mutable MutexLock mutex_;

std::map<:string std::weak_ptr>> stocks_;

};

class StockFactory3 : public boost::noncopyable

{

public:

std::shared_ptr get(const std::string &key);

private:

mutable MutexLock mutex_;

std::map<:string std::weak_ptr>> stocks_;

void deleteStock(Stock *stock);

};

class StockFactory4 : public boost::noncopyable, std::enable_shared_from_this

{

public:

std::shared_ptr get(const std::string &key);

private:

mutable MutexLock mutex_;

std::map<:string std::weak_ptr>> stocks_;

void deleteStock(Stock *stock);

};

class StockFactory5 : public boost::noncopyable, std::enable_shared_from_this

{

public:

std::shared_ptr get(const std::string &key);

private:

mutable MutexLock mutex_;

std::map<:string std::weak_ptr>> stocks_;

static void weakDeleteCallback(const std::weak_ptr &wkFactory, Stock *stock);

void removeStock(Stock *stock);

};

#endif //MUDUO_STOCKFACOTRY_H

StockFactory.cpp

#include "StockFacotry.h"

#include "Mutex.h"

Stock::Stock(const std::string &key) : key_(key){

}

std::string Stock::Key() const

{

return key_;

}

// error, the memory managed by shared_ptr may never be released

std::shared_ptr StockFactory1::get(const std::string &key)

{

MutexLockGuard lock(mutex_);

auto pos = stocks_.find(key);

if(pos != stocks_.end())

{

return pos->second;

} else

{

stocks_[key] = std::shared_ptr(new Stock(key));

return stocks_[key];

}

}

// not that good, the map may contain to many weak_ptr entities.

// stocks_.size() equals the number of all objects including the released ones.

std::shared_ptr StockFactory2::get(const std::string &key) {

std::shared_ptr pStock;

MutexLockGuard lock(mutex_);

std::weak_ptr &wpStock = stocks_[key];

pStock = wpStock.lock();

if(!pStock) // the resource is released in other thread or never exists

{

pStock.reset(new Stock(key));

wpStock = pStock;

}

return pStock;

}

std::shared_ptr StockFactory3::get(const std::string &key) {

std::shared_ptr pStock;

MutexLockGuard lock(mutex_);

std::weak_ptr &wpStock = stocks_[key];

pStock = wpStock.lock();

if(!pStock) // if the resource is released in other thread or never exists

{

// potential risk, this pointer copy is exposed to multi-thread environment in lambda function

// if StockFactory object is destructing in Thread A while Thread B call this function

// there maybe a race condition which leads to core dump

// NOTE for std::bind: this pointer is needed when bind a member function

pStock.reset(new Stock(key), std::bind(&StockFactory3::deleteStock, this, std::placeholders::_1));

wpStock = pStock;

}

return pStock;

}

void StockFactory3::deleteStock(Stock *stock) {

if(stock)

{

MutexLockGuard lock(mutex_);

stocks_.erase(stock->Key());

}

delete stock; //???

}

std::shared_ptr StockFactory4::get(const std::string &key)

{

std::shared_ptr pStock;

MutexLockGuard lock(mutex_);

std::weak_ptr &wpStock = stocks_[key];

pStock = wpStock.lock();

if(!pStock)

{

// the deleteStock function owns a copy of shared_ptr of this, which avoid the race condition

// HOWEVER, a extra copy of shared_ptr in function object may prolong the life of StockFactory by accident

pStock.reset(new Stock(key), std::bind(&StockFactory4::deleteStock, shared_from_this(), std::placeholders::_1));

}

return std::shared_ptr();

}

void StockFactory4::deleteStock(Stock *stock) {

if(stock)

{

MutexLockGuard lock(mutex_);

stocks_.erase(stock->Key());

}

delete stock; //???

}

std::shared_ptr StockFactory5::get(const std::string &key) {

std::shared_ptr pStock;

MutexLockGuard lock(mutex_);

std::weak_ptr &wpStock = stocks_[key];

pStock = wpStock.lock();

if(!pStock) // / the resource is released in other thread or never exists

{

pStock.reset(new Stock(key), std::bind(&StockFactory5::weakDeleteCallback, std::weak_ptr(shared_from_this()), std::placeholders::_1));

}

}

// awesome!!!

// call a member function in a static function via shard_ptr, which requires the object exists in fact

void StockFactory5::weakDeleteCallback(const std::weak_ptr &wkFactory, Stock *stock)

{

std::shared_ptr pFactory = wkFactory.lock();

if(pFactory)

{

pFactory->removeStock(stock);

}

delete stock;

}

void StockFactory5::removeStock(Stock *stock) {

if(stock)

{

MutexLockGuard lock(mutex_);

stocks_.erase(stock->Key());

}

}

原文:https://www.cnblogs.com/jo3yzhu/p/12229195.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值