github位置:codetoys/ctfc.git src/function/LockedList.h
要在线程间安全地操作数据并不容易,安全且高效更不容易。如果降低点性能要求,直接在底层数据上封装互斥层,确保起码不会因为交叉操作而coredump是不太困难的。
下面是个包装起来的List类,只要写代码的时候不要胡来(比如获取指针然后长期持有),基本上就很安全了。所有的基础数据都可以如此包装。
目录
代码
//LockedList.h 带锁定的list
#pragma once
//缺点什么头文件自己加上啊
#include <mutex>
#include <condition_variable>
template<typename T>
class LockedList :private list<T>
{
private:
mutex m_mutex;//互斥锁
public:
using list<T>::iterator;
typename list<T>::iterator locked_begin()
{
m_mutex.lock();
typename list<T>::iterator it = this->begin();
m_mutex.unlock();
return it;
}
typename list<T>::iterator locked_end()
{
m_mutex.lock();
typename list<T>::iterator it = this->end();
m_mutex.unlock();
return it;
}
size_t locked_size()
{
m_mutex.lock();
size_t ret = this->size();
m_mutex.unlock();
return ret;
}
void locked_push_back(T const& data)
{
m_mutex.lock();
this->push_back(data);
m_mutex.unlock();
}
void locked_push_front(T const& data)
{
m_mutex.lock();
this->push_front(data);
m_mutex.unlock();
}
void locked_pop_front()
{
m_mutex.lock();
this->pop_front();
m_mutex.unlock();
}
void locked_clear()
{
m_mutex.lock();
this->clear();
m_mutex.unlock();
}
};
要点
mutex
这是最简单的互斥对象,大多数情况下,仅仅使用最简单的互斥对象是最有效也最可靠的。
私有继承,保证没有任何一个操作不受保护
如果不用私有继承,改用私有成员也是可以的。
typename的使用
新的语言规范要求各种带::加上typename,以前是不需要的。
方法名称
我为了清晰都加了locked_前缀,其实不加也是可以的。这要看你有多少旧代码需要修改。
这是一种很常见的包装类
通过包装拦截或者增加功能而又尽量不改变原有客户代码,这依赖合理的层次设计。
(这里是结束)