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.