c++ - 带有线程的 deque::push_back react 异常

标签 c++ multithreading deque

我尝试过不同的方法,但双端队列容器中线程的 push_back react 异常。

为什么会这样??这是因为复制/移动构造函数吗?

这里是程序的输出...

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.

关于c++ - 带有线程的 deque::push_back react 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41364426/

相关文章:

c++ - 为什么我的 vector 中的字符串不改变值?

c++ - 如何使用用户定义的函数在 C++ 中创建累加器?

java - BlockingQueue 中阻塞的线程

c++ - 为什么双端队列比队列快?

c++ - 如何定义类似于Vector的Vector的Double Brackets/Double Iterator运算符?

c++ - STL deque 会重新分配我的元素(c++)吗?

c++ - 如何区分数值的使用和 #define 与 Clang 的使用?

c++ - 公开基类枚举而不用乏味地列出枚举数

windows - 从另一个线程调用 OpenGL 函数

java - 我的 while 循环对于我的方法来说是否太快?