首页 > 解决方案 > 将我的线程计时器类移动到一个向量中并在同一个循环中开始有一个奇怪的效果

问题描述

我有一个我写的计时器类。任何单个计时器似乎都可以完美运行。我试图将它们的负载添加到向量并启动它们的负载,但是因为它有一个线程成员,我需要编写一个移动/复制构造函数。我决定让它只移动(非复制)。所以现在我可以将计时器添加到向量中(注意底部的完整代码链接)。

但是我注意到一些奇怪的行为。这是我将计时器添加到向量的方法(请参见注 1 和 2):

int main()
{
    // Due to godbolt's limited resources (I think) I could only add 3
    constexpr size_t num = 3;
    std::vector<timer> timers;
    for (size_t i = 0; i < num; i++)
    {
        timer tmr;
        timers.emplace_back(std::move(tmr));
        // NOTE 1: this way does not work quite right
        // timers[i].start(100, [i]{ std::cout << i << std::flush; }, false);
    }

    // NOTE 2: So I now start the timers in a second loop which seems to work
    for (size_t i = 0; i < num; i++)
    {
        timers[i].start(100, [i]{ std::cout << i << std::flush; }, false);
    }

    // Let the timers run for a while
    SLEEP_MSEC(1000);

    std::cout << "\n============ end ==============" << std::endl;
    return 0;    
}

当我运行它时,我得到以下输出(每个计时器都应该打印它的数字,所以 0,1 和 2):

move c'tor
~timer()
move c'tor
move c'tor
~timer()
~timer()
move c'tor
move c'tor
move c'tor
~timer()
~timer()
~timer()
210120210102021210120201102   <------- HERE all timers running
============ end ==============
~timer()
~timer()
~timer()

当我删除第二个循环并重新启用在我得到的第一个循环内启动计时器时(每个计时器应该打印它的编号,但只有 2 个正在打印):

move c'tor
~timer()
move c'tor
move c'tor
~timer()
~timer()
move c'tor
move c'tor
move c'tor
~timer()
~timer()
~timer()
222222222       <-------- HERE only the last timer seems to run
============ end ==============
~timer()
~timer()
~timer()

这是关于非工作循环的 Godbolt 设置的完整代码: https ://godbolt.org/z/fFtjt2

两者似乎都输出正确数量的移动/析构函数以及在正确的时间等。但我无法在这里发现问题。我的猜测是我做错了移动构造函数,但我不明白为什么。

标签: c++multithreadingc++11vectorstdmove

解决方案


推荐阅读