读写锁实现
使用2个互斥锁实现读写锁
class readwrite_lock
{
public:
readwrite_lock()
: read_cnt(0)
{
}
void readLock()
{
read_mtx.lock();
if (++read_cnt == 1)
write_mtx.lock();
read_mtx.unlock();
}
void readUnlock()
{
read_mtx.lock();
if (--read_cnt == 0)
write_mtx.unlock();
read_mtx.unlock();
}
void writeLock()
{
write_mtx.lock();
}
void writeUnlock()
{
write_mtx.unlock();
}
private:
mutex read_mtx;
mutex write_mtx;
int read_cnt; // 已加读锁个数
};
使用互斥锁和条件变量实现读写锁
class readwrite_lock
{
public:
readwrite_lock()
: stat(0)
{
}
void readLock()
{
mtx.lock();
while (stat < 0)
cond.wait(mtx);
++stat;
mtx.unlock();
}
void readUnlock()
{
mtx.lock();
if (--stat == 0)
cond.notify_one(); // 叫醒一个等待的写操作
mtx.unlock();
}
void writeLock()
{
mtx.lock();
while (stat != 0)
cond.wait(mtx);
stat = -1;
mtx.unlock();
}
void writeUnlock()
{
mtx.lock();
stat = 0;
cond.notify_all(); // 叫醒所有等待的读和写操作
mtx.unlock();
}
private:
mutex mtx;
condition_variable cond;
int stat; // == 0 无锁;> 0 已加读锁个数;< 0 已加写锁
};
智能指针实现
指针计数类
class PtrCounter
{
public:
PtrCounter(): count{1} {}
void add(){++count;}
void subtract(){--count;}
int get() const{return count;}
private:
std::atomic<int> count;
};
共享指针模板类
template<typename T>
class SharePtr
{
public:
SharePtr(T* ptr) : my_ptr{ptr}, my_ref_count{new PtrCounter} {}
SharePtr() : my_ptr(nullptr),my_ref_count(new PtrCounter){}
SharePtr(const SharePtr &p)
{
this->my_ptr = p.my_ptr;
this->my_ref_count = p.my_ref_count;
my_ref_count->add();
}
SharePtr& operator = (const SharePtr &p)
{
clear();
this->my_ptr = p.my_ptr;
this->my_ref_count = p.my_ref_count;
my_ref_count->add();
return *this;
}
SharePtr(SharePtr &&p)
{
this->my_ptr = p.my_ptr;
this->my_ref_count = p.my_ref_count;
p.my_ptr = nullptr;
p.my_ref_count = nullptr;
}
SharePtr &operator =(SharePtr &&p)
{
clear();
this->my_ptr = p.my_ptr;
this->my_ref_count = p.my_ref_count;
p.my_ptr = nullptr;
p.my_ref_count = nullptr;
return *this;
}
~SharePtr(){clear();}
int use_count() {return my_ref_count->get();}
T* get() const {return my_ptr;}
T* operator->() const {return *my_ptr;}
T& operator*() const {return *my_ptr;}
operator bool() const {return my_ptr;}
private:
T* my_ptr;
PtrCounter* my_ref_count;
void clear()
{
if(my_ref_count)
{
my_ref_count->subtract();
if(my_ref_count->get() == 0)
{
if(my_ptr) delete my_ptr;
delete my_ref_count;
}
}
}
};