假设我有一堂课:
class WonnaBeMovedClass
{
public:
WonnaBeMovedClass(WonnaBeMovedClass&& other);
void start();
private:
void updateSharedData();
std::vector<int> _sharedData;
std::thread _threadUpdate;
std::mutex _mutexShaderData;
//other stuff
};
WonnaBeMovedClass::WonnaBeMovedClass(WonnaBeMovedClass&& other)
{
_sharedData = std::move(other._sharedData);
_threadUpdate = std::move(other._threadUpdate);
_mutexShaderData = std::move(other._mutexShaderData); //won't compile.
}
void WonnaBeMovedClass::start()
{
_threadUpdate = std::thread(&updateSharedData, this);
}
void WonnaBeMovedClass::updateSharedData()
{
std::lock_guard<std::mutex> lockSharedData(_mutexShaderData);
for (auto& value : _sharedData)
{
++value;
}
}
由于互斥体无法移动,因此无法编译。这没有道理。然后,我认为可以通过使用指针而不是实际变量来解决此问题,并提出了以下建议:
class WonnaBeMovedClass
{
public:
WonnaBeMovedClass(WonnaBeMovedClass&& other);
void start();
private:
void updateSharedData();
std::vector<int> _sharedData;
std::unique_ptr<std::thread> _threadUpdate //pointer;
std::unique_ptr<std::mutex> _mutexShaderData //pointer;
//other stuff
};
WonnaBeMovedClass::WonnaBeMovedClass(WonnaBeMovedClass&& other)
{
_sharedData = std::move(other._sharedData);
_threadUpdate = std::move(other._threadUpdate);
_mutexShaderData = std::move(other._mutexShaderData); //won't compile.
}
void WonnaBeMovedClass::start()
{
_threadUpdate = std::make_unique<std::thread>(&updateSharedData, this);
}
void WonnaBeMovedClass::updateSharedData()
{
std::lock_guard<std::mutex> lockSharedData(*_mutexShaderData);
for (auto& value : _sharedData)
{
++value;
}
}
所以现在当我:
WonnaBeMovedClass object1;
WonnaBeMovedClass object2;
//do stuff
object1 = std::move(object2);
我实际上同时移动了互斥锁和线程的地址。现在更有意义了……还是不?
该线程仍在处理object1而不是object2的数据,因此它仍然没有任何意义。我可能已经移动了互斥量,但是线程不知道object2。还是?我找不到答案,所以我想向您寻求帮助。
我是在做完全错误的事情,并且复制/移动线程和互斥体只是一个不好的设计,我应该重新考虑程序的体系结构?
关于班级的实际目的存在疑问。它实际上是一个TCP / IP客户端(以类表示),它拥有:
一次可以建立多个连接,因此在代码中某处有一个std::vector<Client>
字段代表所有活动连接。连接由配置文件确定。
//read configurations
...
//init clients
for (auto& configuration : _configurations)
{
Client client(configuration);
_activeClients.push_back(client); // this is where compiler reminded me that I am unable to move my object (aka WonnaBeMovedClass object).
}}
我_activeClients
已从更改为std::vector<Client>
,std::vector<std::unique_ptr<Client>>
并修改了初始化代码,以直接创建指针对象而不是对象,并且可以解决我的问题,但是问题仍然存在,因此我决定将其发布在此处。
让我们将问题分成两部分。
std::function
存储在某处或任何地方)具有数据的地址并可以访问。实际上,这与前面的情况非常相似,只是代替了操作系统,它是保存数据的您自己的代码。和以前一样,解决方案是不移动数据。而是将(智能)指针存储并移动到数据。总而言之,
class WonnaBeMovedClass
{
public:
WonnaBeMovedClass
(WonnaBeMovedClass&& other);
void start();
private:
struct tdata {
std::vector<int> _sharedData;
std::thread _threadUpdate;
std::mutex _mutexShaderData;
};
std::shared_ptr<tdata> data;
static void updateSharedData(std::shared_ptr<tdata>);
};
void WonnaBeMovedClass::start()
{
_threadUpdate = std::thread(&updateSharedData, data);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句