制作一个安全的 Reader/Writer 向量
Make a safe Reader/Writer vector
受到this code的启发,我正在尝试实现一个Reader/Writervector
,它可以安全地通过线程并发调用push_back()
。
一旦这个 class 到位,我可能会通过调用 std::swap()
创建方法 erase()
,它交换目标项目和最后一个项目,然后删除最后一个项目集合。这样,我假设性能应该是公平的,因为删除集合中间的项目不会调用移动集合中目标项目之后的所有项目。
不幸的是,下面的代码:
#include <vector>
#include <boost/thread/shared_mutex.hpp> //shared_mutex
#include <memory> //shared_ptr
#include <utility> //swap()
template <class T>
class readers_writer_vector
{
std::shared_ptr<boost::shared_mutex> pm;
std::vector<T> data;
public:
readers_writer_vector() :
pm(new std::shared_ptr<boost::shared_mutex>){}
void push_back(const T& item){
boost::unique_lock<boost::shared_mutex> lock(*pm); //wrong design
data.push_back(item);
}
};
int main()
{
readers_writer_vector<int> db;
db.push_back(1);
return 0;
}
产生以下编译错误:
/usr/include/c++/4.9/bits/shared_ptr_base.h:871:39: error: cannot convert ‘std::shared_ptr<boost::shared_mutex>*’ to ‘boost::shared_mutex*’ in initialization
: _M_ptr(__p), _M_refcount(__p)
// g++ -std=c++11 -Iboost -lboost t.cpp
我该如何解决?请!
编辑:
实施任务远比我想象的复杂。没过多久,我就遇到了@Danh 警告过的问题。现在我得到这些错误:
t.cpp:28:8: note: ‘i::i(const i&)’ is implicitly deleted because the default definition would be ill-formed:
struct i {
^
t.cpp:28:8: error: use of deleted function ‘readers_writer_vector<T>::readers_writer_vector(const readers_writer_vector<T>&) [with T = z]’
t.cpp:13:2: note: declared here
readers_writer_vector(readers_writer_vector const&) = delete;
使用此版本:
template <class T>
class readers_writer_vector
{
booster::shared_mutex m;
std::vector<T> data;
public:
readers_writer_vector() = default;
readers_writer_vector(readers_writer_vector const&) = delete;
void push_back(const T& item){
booster::unique_lock<booster::shared_mutex> lock(m);
data.push_back(item);
}
typename std::vector<T>::reference back(){
return data.back();
}
};
struct z {
int zipcode;
std::string address;
};
struct i {
int id;
readers_writer_vector<z> zipcodes;
};
int main()
{
readers_writer_vector<i> db;
db.push_back(i());
auto &ii=db.back();
ii.id=1;
ii.zipcodes.push_back(z());
auto &zz=ii.zipcodes.back();
zz.zipcode=11;
zz.address="aa";
return 0;
}
除了修复现有的错误之外,我还必须为 readers_writer_vector
实现迭代器以使这个 class 有用。
我在考虑要不要继续...
因为 pm
是 std::shared_ptr<boost::shared_mutex>
而不是 std::shared_ptr<boost::shared_mutex>*
。你可以使用这个:
readers_writer_vector() :
pm(std::make_shared<boost::shared_mutex>()){}
无论如何,为什么需要 pointer/smart 指针?这更适合:
template <class T>
class readers_writer_vector
{
boost::shared_mutex pm;
std::vector<T> data;
public:
void push_back(const T& item){
boost::unique_lock<boost::shared_mutex> lock(pm);
data.push_back(item);
}
};
您初始化 pm
的类型有误;你实际上有
std::shared_ptr<> pm = new std::shared_ptr<>;
您不能将共享指针从一个指针分配给共享指针。
将初始化程序替换为
pm(new boost::shared_mutex)
或者直接将互斥量设为成员,而不是使用共享指针。
受到this code的启发,我正在尝试实现一个Reader/Writervector
,它可以安全地通过线程并发调用push_back()
。
一旦这个 class 到位,我可能会通过调用 std::swap()
创建方法 erase()
,它交换目标项目和最后一个项目,然后删除最后一个项目集合。这样,我假设性能应该是公平的,因为删除集合中间的项目不会调用移动集合中目标项目之后的所有项目。
不幸的是,下面的代码:
#include <vector>
#include <boost/thread/shared_mutex.hpp> //shared_mutex
#include <memory> //shared_ptr
#include <utility> //swap()
template <class T>
class readers_writer_vector
{
std::shared_ptr<boost::shared_mutex> pm;
std::vector<T> data;
public:
readers_writer_vector() :
pm(new std::shared_ptr<boost::shared_mutex>){}
void push_back(const T& item){
boost::unique_lock<boost::shared_mutex> lock(*pm); //wrong design
data.push_back(item);
}
};
int main()
{
readers_writer_vector<int> db;
db.push_back(1);
return 0;
}
产生以下编译错误:
/usr/include/c++/4.9/bits/shared_ptr_base.h:871:39: error: cannot convert ‘std::shared_ptr<boost::shared_mutex>*’ to ‘boost::shared_mutex*’ in initialization
: _M_ptr(__p), _M_refcount(__p)
// g++ -std=c++11 -Iboost -lboost t.cpp
我该如何解决?请!
编辑:
实施任务远比我想象的复杂。没过多久,我就遇到了@Danh 警告过的问题。现在我得到这些错误:
t.cpp:28:8: note: ‘i::i(const i&)’ is implicitly deleted because the default definition would be ill-formed:
struct i {
^
t.cpp:28:8: error: use of deleted function ‘readers_writer_vector<T>::readers_writer_vector(const readers_writer_vector<T>&) [with T = z]’
t.cpp:13:2: note: declared here
readers_writer_vector(readers_writer_vector const&) = delete;
使用此版本:
template <class T>
class readers_writer_vector
{
booster::shared_mutex m;
std::vector<T> data;
public:
readers_writer_vector() = default;
readers_writer_vector(readers_writer_vector const&) = delete;
void push_back(const T& item){
booster::unique_lock<booster::shared_mutex> lock(m);
data.push_back(item);
}
typename std::vector<T>::reference back(){
return data.back();
}
};
struct z {
int zipcode;
std::string address;
};
struct i {
int id;
readers_writer_vector<z> zipcodes;
};
int main()
{
readers_writer_vector<i> db;
db.push_back(i());
auto &ii=db.back();
ii.id=1;
ii.zipcodes.push_back(z());
auto &zz=ii.zipcodes.back();
zz.zipcode=11;
zz.address="aa";
return 0;
}
除了修复现有的错误之外,我还必须为 readers_writer_vector
实现迭代器以使这个 class 有用。
我在考虑要不要继续...
因为 pm
是 std::shared_ptr<boost::shared_mutex>
而不是 std::shared_ptr<boost::shared_mutex>*
。你可以使用这个:
readers_writer_vector() :
pm(std::make_shared<boost::shared_mutex>()){}
无论如何,为什么需要 pointer/smart 指针?这更适合:
template <class T>
class readers_writer_vector
{
boost::shared_mutex pm;
std::vector<T> data;
public:
void push_back(const T& item){
boost::unique_lock<boost::shared_mutex> lock(pm);
data.push_back(item);
}
};
您初始化 pm
的类型有误;你实际上有
std::shared_ptr<> pm = new std::shared_ptr<>;
您不能将共享指针从一个指针分配给共享指针。
将初始化程序替换为
pm(new boost::shared_mutex)
或者直接将互斥量设为成员,而不是使用共享指针。