gpt4 book ai didi

c++ - Boost,指向互斥量的指针,这行得通吗? boost::mutex 和 std::vector,不可复制的问题

转载 作者:搜寻专家 更新时间:2023-10-31 00:18:54 26 4
gpt4 key购买 nike

下面的代码会给我一个错误,因为 boost::mutex 是不可复制的,而 xyz.push_back() 是一个复制构造函数。

class XYZ
{
public:
double x;
boost::mutex x_mutex;
}

vector<XYZ> xyz;
xyz.push_back(XYZ());

所以我尝试了这样的事情,

class XYZ
{
public:
double x;
boost::mutex * x_mutex;
}

vector<XYZ> xyz;
xyz.push_back(XYZ());

它符合没有错误,但问题是“那个互斥锁真的会按它应该的方式工作吗?”这是将互斥量封装在类中然后创建该类的 vector 的好方法吗?

谢谢。

最佳答案

这里有两个问题:

  1. 是否会正确创建互斥锁?

  2. 是否会正确使用互斥体?

因为问题成立,所以 1. 的答案是否定的。互斥量指针未指向互斥量。

所以你需要添加一个合适的构造函数。由于您需要一个构造函数,如果您希望您的类能够正确运行,您可能需要实现一个析构函数、复制构造函数和赋值运算符。

要么

XYZ::XYZ() : x(0), x_mutex(new boost::mutex) {}
XYZ::~XYZ() { delete x_mutex; }
XYZ::XYZ( const XYZ & xyz ) : x(xyz.x), x_mutex( new boost::mutex ) {}
XYZ& XYZ::operator=( const XYZ & xyz ) { x=xyz.x; }

explicit XYZ::XYZ( boost::mutex * m ) : x(0), x_mutex(m) {}
// Strictly speaking we dont need these as the default version does the right thing.
XYZ::~XYZ() {}
XYZ::XYZ( const XYZ & xyz ) : x(xyz.x), x_mutex( xyz.x_mutex ) {}
XYZ& XYZ::operator=( const XYZ & xyz ) { x=xyz.x; x_mutex = xyz.x_mutex; }

会是我所期望的。

在第一种情况下,对象的每个实例和拷贝都有自己的互斥量。在第二种情况下,每个对象与其拷贝共享一个互斥锁,但互斥锁必须在实例之前创建。

还有第三种变体,其中互斥量可以由构造函数创建并与所有实例共享,但要做到这一点,您需要持有指向互斥量的 shared_ptr 而不是原始指针。

class XYZ
{
public:
double x;
boost::shared_ptr<boost::mutex> x_mutex;
XYZ() : x(0), x_mutex( new boost::mutex ) {}
// Default versions of the other three do the right thing.
};

如果我们沿着这些路径中的任何一条走下去,我们最终会遇到正确创建和初始化互斥锁的情况。

现在是棘手的部分“是否会正确使用互斥体?”。要回答这个问题,我们需要知道对象是如何在线程之间共享的,互斥体应该保护的共享数据是什么。

如果对象 vector 是在创建任何工作线程之前在主线程中创建的,并且每个对象实例都被工作线程修改(以便互斥体真正保护 x 数据)那么第一个版本可能是正确的.在这种情况下,您的代码看起来更像这样。

//Main thread
std::vector<XYZ> v;
for(unsigned int i=0; i<10; ++i)
v.push_back(XYZ());

//Several worker threads like this
j = rand()%10;
v[j].x_mutex->lock();
v[j].x+=1;
v[j].x_mutex->unlock();

如果 x 确实是一个指针类型并且它所指向的东西在线程之间共享,那么您的代码可能看起来像这样,并且要使用的代码的正确版本是 2 或 3。

//Main thread
std::vector<XYZ> v;
X * xa;
boost::mutex xa_mutex;
X * xb;
boost::mutex xb_mutex;

for(unsigned int i=0; i<5; ++i)
v.push_back(XYZ(xa,xa_mutex));

for(unsigned int i=0; i<5; ++i)
v.push_back(XYZ(xb,xb_mutex));

//Several worker threads like this
j = rand()%10;
v[j].x_mutex->lock();
v[j].x->do_something();
v[j].x_mutex->unlock();

关键是每个共享资源有一个互斥量。

请注意,从技术上讲, vector v 在这两种情况下都是共享资源,如果它在创建后要更改,也应该受到互斥量的保护。然而,这样的锁会(正确地)破坏所有并行性..所以让我们暂时忽略它;)

关于c++ - Boost,指向互斥量的指针,这行得通吗? boost::mutex 和 std::vector,不可复制的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9320533/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com