deque::push_back 线程反应异常
deque::push_back with threads reacts strangely
我尝试了不同的方法,但是双端队列容器中的 push_back 个线程反应异常。
为什么会这样??这是因为 copy/move 构造函数吗?
这里是程序的输出...
progress[0]:-1
progress[1]:-1
executing threads...
progress[0]:100
progress[1]:100
================================
progress[0]:-1
progress[1]:-1
executing threads...
progress[0]:-1
progress[1]:100
如输出所示,结果在使用
之间延迟
for(size_t i = 0; i < 2; ++i) {
deq.push_back(th(&progress[i]));
}
和
deq.push_back(th(&progress[0]));
deq.push_back(th(&progress[1]));
这是源代码...
class th {
public:
void func() {
*this->progress = 100;
}
th(int* prog) :
progress(prog),
m_thread(std::thread(&th::func, this)) {};
// COPY
th(th const& other);
th& operator=(th const& other);
// MOVE
th(th&&) = default;
// th& operator=(th&& other) {
// if(this != &other){
// }
// return *this;
// }
void join() { m_thread.join(); }
int *progress;
private:
std::thread m_thread;
};
int main(void) {
{
std::vector<int> progress;
progress.push_back(-1);
progress.push_back(-1);
std::deque<th> deq;
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
std::cout << "executing threads..." << std::endl;
deq.push_back(th(&progress[0]));
deq.push_back(th(&progress[1]));
for (std::deque<th>::iterator it = deq.begin(); it != deq.end(); it++) {
it->join();
// deq.erase(it);
}
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
}
std::cout << "================================" << std::endl;
{
std::vector<int> progress;
progress.push_back(-1);
progress.push_back(-1);
std::deque<th> deq;
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
std::cout << "executing threads..." << std::endl;
for(size_t i = 0; i < 2; ++i) {
deq.push_back(th(&progress[i]));
}
for (std::deque<th>::iterator it = deq.begin(); it != deq.end(); it++) {
it->join();
// deq.erase(it);
}
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
}
exit(EXIT_SUCCESS);
}
以及如何在没有编译器抱怨的情况下使用 deque 的 erase 成员函数
/home/user/test/obj/main.o: In function `__gnu_cxx::_Mutable_BidirectionalIteratorConcept<th*>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx37_Mutable_BidirectionalIteratorConceptIP2thE13__constraintsEv[__gnu_cxx::_Mutable_BidirectionalIteratorConcept<th*>::__constraints()]+0x40): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `__gnu_cxx::_ConvertibleConcept<th, th>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx19_ConvertibleConceptI2thS1_E13__constraintsEv[__gnu_cxx::_ConvertibleConcept<th, th>::__constraints()]+0x20): undefined reference to `th::th(th const&)'
/home/user/test/obj/main.o: In function `__gnu_cxx::_OutputIteratorConcept<th*, th>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx22_OutputIteratorConceptIP2thS1_E13__constraintsEv[__gnu_cxx::_OutputIteratorConcept<th*, th>::__constraints()]+0x64): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `th* std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b<th*, th*>(th*, th*, th*)':
main.cpp:(.text._ZNSt20__copy_move_backwardILb1ELb0ESt26random_access_iterator_tagE13__copy_move_bIP2thS4_EET0_T_S6_S5_[th* std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b<th*, th*>(th*, th*, th*)]+0x5c): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `th* std::__copy_move<true, false, std::random_access_iterator_tag>::__copy_m<th*, th*>(th*, th*, th*)':
main.cpp:(.text._ZNSt11__copy_moveILb1ELb0ESt26random_access_iterator_tagE8__copy_mIP2thS4_EET0_T_S6_S5_[th* std::__copy_move<true, false, std::random_access_iterator_tag>::__copy_m<th*, th*>(th*, th*, th*)]+0x44): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `__gnu_cxx::_Mutable_ForwardIteratorConcept<th*>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx31_Mutable_ForwardIteratorConceptIP2thE13__constraintsEv[__gnu_cxx::_Mutable_ForwardIteratorConcept<th*>::__constraints()]+0x3c): undefined reference to `th::operator=(th const&)'
collect2: ld returned 1 exit status
make: *** [link] Error 1
谢谢!
你将this
的值(即对象的当前地址)传递给std::thread
的构造函数。将 th
对象移入双端队列后,this
的值不再有效,因为对象现在已移至不同的位置。然而线程仍然使用旧值。尝试使 th
不可移动并使用 emplace_back
而不是 push_back
.
class th {
public:
void func() {
*this->progress = 100;
}
explicit th(int* prog) :
progress(prog),
m_thread(std::thread(&th::func, this)) {};
// COPY
th(th const& other) = delete;
th(th && other) = delete;
th& operator=(th const& other) = delete;
th& operator=(th &&) = delete;
void join() { m_thread.join(); }
int *progress;
private:
std::thread m_thread;
};
std::vector<int> progress;
progress.push_back(-1);
progress.push_back(-1);
std::deque<th> deq;
deq.emplace_back (&progress[0]);
// etc.
我尝试了不同的方法,但是双端队列容器中的 push_back 个线程反应异常。
为什么会这样??这是因为 copy/move 构造函数吗?
这里是程序的输出...
progress[0]:-1
progress[1]:-1
executing threads...
progress[0]:100
progress[1]:100
================================
progress[0]:-1
progress[1]:-1
executing threads...
progress[0]:-1
progress[1]:100
如输出所示,结果在使用
之间延迟for(size_t i = 0; i < 2; ++i) {
deq.push_back(th(&progress[i]));
}
和
deq.push_back(th(&progress[0]));
deq.push_back(th(&progress[1]));
这是源代码...
class th {
public:
void func() {
*this->progress = 100;
}
th(int* prog) :
progress(prog),
m_thread(std::thread(&th::func, this)) {};
// COPY
th(th const& other);
th& operator=(th const& other);
// MOVE
th(th&&) = default;
// th& operator=(th&& other) {
// if(this != &other){
// }
// return *this;
// }
void join() { m_thread.join(); }
int *progress;
private:
std::thread m_thread;
};
int main(void) {
{
std::vector<int> progress;
progress.push_back(-1);
progress.push_back(-1);
std::deque<th> deq;
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
std::cout << "executing threads..." << std::endl;
deq.push_back(th(&progress[0]));
deq.push_back(th(&progress[1]));
for (std::deque<th>::iterator it = deq.begin(); it != deq.end(); it++) {
it->join();
// deq.erase(it);
}
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
}
std::cout << "================================" << std::endl;
{
std::vector<int> progress;
progress.push_back(-1);
progress.push_back(-1);
std::deque<th> deq;
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
std::cout << "executing threads..." << std::endl;
for(size_t i = 0; i < 2; ++i) {
deq.push_back(th(&progress[i]));
}
for (std::deque<th>::iterator it = deq.begin(); it != deq.end(); it++) {
it->join();
// deq.erase(it);
}
std::cout << "progress[0]:" << progress[0] << std::endl;
std::cout << "progress[1]:" << progress[1] << std::endl;
}
exit(EXIT_SUCCESS);
}
以及如何在没有编译器抱怨的情况下使用 deque 的 erase 成员函数
/home/user/test/obj/main.o: In function `__gnu_cxx::_Mutable_BidirectionalIteratorConcept<th*>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx37_Mutable_BidirectionalIteratorConceptIP2thE13__constraintsEv[__gnu_cxx::_Mutable_BidirectionalIteratorConcept<th*>::__constraints()]+0x40): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `__gnu_cxx::_ConvertibleConcept<th, th>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx19_ConvertibleConceptI2thS1_E13__constraintsEv[__gnu_cxx::_ConvertibleConcept<th, th>::__constraints()]+0x20): undefined reference to `th::th(th const&)'
/home/user/test/obj/main.o: In function `__gnu_cxx::_OutputIteratorConcept<th*, th>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx22_OutputIteratorConceptIP2thS1_E13__constraintsEv[__gnu_cxx::_OutputIteratorConcept<th*, th>::__constraints()]+0x64): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `th* std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b<th*, th*>(th*, th*, th*)':
main.cpp:(.text._ZNSt20__copy_move_backwardILb1ELb0ESt26random_access_iterator_tagE13__copy_move_bIP2thS4_EET0_T_S6_S5_[th* std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b<th*, th*>(th*, th*, th*)]+0x5c): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `th* std::__copy_move<true, false, std::random_access_iterator_tag>::__copy_m<th*, th*>(th*, th*, th*)':
main.cpp:(.text._ZNSt11__copy_moveILb1ELb0ESt26random_access_iterator_tagE8__copy_mIP2thS4_EET0_T_S6_S5_[th* std::__copy_move<true, false, std::random_access_iterator_tag>::__copy_m<th*, th*>(th*, th*, th*)]+0x44): undefined reference to `th::operator=(th const&)'
/home/user/test/obj/main.o: In function `__gnu_cxx::_Mutable_ForwardIteratorConcept<th*>::__constraints()':
main.cpp:(.text._ZN9__gnu_cxx31_Mutable_ForwardIteratorConceptIP2thE13__constraintsEv[__gnu_cxx::_Mutable_ForwardIteratorConcept<th*>::__constraints()]+0x3c): undefined reference to `th::operator=(th const&)'
collect2: ld returned 1 exit status
make: *** [link] Error 1
谢谢!
你将this
的值(即对象的当前地址)传递给std::thread
的构造函数。将 th
对象移入双端队列后,this
的值不再有效,因为对象现在已移至不同的位置。然而线程仍然使用旧值。尝试使 th
不可移动并使用 emplace_back
而不是 push_back
.
class th {
public:
void func() {
*this->progress = 100;
}
explicit th(int* prog) :
progress(prog),
m_thread(std::thread(&th::func, this)) {};
// COPY
th(th const& other) = delete;
th(th && other) = delete;
th& operator=(th const& other) = delete;
th& operator=(th &&) = delete;
void join() { m_thread.join(); }
int *progress;
private:
std::thread m_thread;
};
std::vector<int> progress;
progress.push_back(-1);
progress.push_back(-1);
std::deque<th> deq;
deq.emplace_back (&progress[0]);
// etc.