如何创建对象的 std::vector,并且每个对象内部封装有一个 boost::thread 。
class INSTRUMENT {
public:
INSTRUMENT() : m_thread(new boost::thread(&INSTRUMENT::Start, this)) {
x = "abc";
}
~INSTRUMENT() {}
void Start();
public:
std::string x;
boost::shared_ptr<boost::thread> m_thread;
};
void INSTRUMENT::Start() {
try {
while (1) {
boost::this_thread::interruption_point();
std::cout << "here " << x << std::endl;
}
} catch (boost::thread_interrupted &thread_e) {
std::cout << "exit " << x << std::endl;
} catch (std::exception &e) {
}
}
std::vector<INSTRUMENT> m_inst_vector;
for (int i = 0; i < 5; i++) {
m_inst_vector.push_back(INSTRUMENT());
}
代码编译得很好,但输出只是一些垃圾,而不是预期的“abc”。在调试中,我注意到每次调用 .push_back() 时都会调用 ~INSTRUMENT() 。
由于当前设计的限制,我尝试不使用boost::group_thread。只是想知道是否有可能有一个带有线程的对象的 std::vector ,或者对类似设计的任何建议都会非常有帮助。
我在 SO 上找到了类似的帖子。它提到了编译器支持的移动语义,但没有解释它是什么。 How can I add boost threads to a vector
谢谢。
最佳答案
这段代码有两个问题。
首先,线程在 boost::thread
后立即开始运行。对象已构造,因此您需要确保它访问的任何数据都已预先初始化 --- 即初始化 x
在构造线程之前在成员初始化列表中。
其次,该线程使用this
INSTRUMENT
的指针对象,因此您的对象被绑定(bind)到特定的地址。 std::vector
复制周围的值:当您调用 push_back
时然后它将对象复制到 vector 中,如果必须分配新的内存块以腾出空间,则添加其他元素可能会复制其他元素。这就是您看到的析构函数调用的原因:构造了临时变量,push_back
将其复制到 vector ,然后临时对象被破坏。
要解决此问题,您需要确保一旦构建了 INSTRUMENT
对象无法移动或复制,因为拷贝具有错误的语义。通过将复制构造函数和赋值运算符设置为私有(private)且未实现(或者如果您有支持此新 C++11 构造的最新编译器,则将它们标记为已删除),或从 boost::noncopyable
派生来实现此目的。 。完成此操作后,您不再需要 shared_ptr
对于线程来说,由于它不能共享,所以直接构造即可。
如果INSTRUMENT
不可复制,您不能将其直接存储在 vector 中,因此请使用类似 boost::shared_ptr<INSTRUMENT>
的内容在 vector 中。这将允许 vector 自由复制和重新排列其元素,而不影响 INSTRUMENT
的地址。对象,并确保它在最后被正确销毁。
class INSTRUMENT: boost::noncopyable {
public:
INSTRUMENT() : x("abc"),m_thread(&INSTRUMENT::Start, this) {
}
~INSTRUMENT() {}
void Start();
public:
std::string x;
boost::thread m_thread;
};
void INSTRUMENT::Start() {
try {
while (1) {
boost::this_thread::interruption_point();
std::cout << "here " << x << std::endl;
}
} catch (boost::thread_interrupted &thread_e) {
std::cout << "exit " << x << std::endl;
} catch (std::exception &e) {
}
}
std::vector<boost::shared_ptr<INSTRUMENT> > m_inst_vector;
for (int i = 0; i < 5; i++) {
m_inst_vector.push_back(boost::shared_ptr<INSTRUMENT>(new INSTRUMENT));
}
关于c++ - std::对象 vector ,其中封装有 boost::thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9407378/