linux std::thread不执行C++函数

6tqwzwtp  于 12个月前  发布在  Linux
关注(0)|答案(1)|浏览(113)

我有这个简单的功能:

class Timer {
    std::atomic<bool> active{true};
    
    public:
         
        void setInterval(auto function, int interval);
        void stop();

};

void Timer::setInterval(auto function, int interval) {
    active = true;
    std::thread t([=]() {
        while(active.load()) {
            std::this_thread::sleep_for(std::chrono::milliseconds(interval));
            if(!active.load()) return;
            function();
        }
    });
    t.detach();
}

void Timer::stop() {
    active = false;
}

字符串
现在,当我尝试运行它时:

int main()
{
    printf("start\n");
    Timer* timer = new Timer();
    timer->setInterval([&]() {
        std::cout << "hello" << std::endl;
    },1000); 
    return 0;
};


只有从主类打印的开始,它永远不会到达setInterval函数中的函数。它只是停止应用程序,没有错误。
compile/link命令:

/usr/bin/g++ -fdiagnostics-color=always -std=c++14 -pthread -g /home/vagrant/cpp/batch/main.cpp -o /home/vagrant/cpp/batch/main

7tofc5zh

7tofc5zh1#

下面是正确使用线程对象来运行计时器的众多方法之一。

#include <atomic>
#include <thread>
#include <chrono>
#include <iostream>

class Timer {
  private:
    std::atomic<bool> active = false;
    std::unique_ptr<std::thread> timer_thread;

  public:
    // this class needs a destructor.
    ~Timer()
    {
        stop();
    }

    // this function name is misleading, 
    // void setInterval(auto function, int interval);
    //
    // let's rename it to what it does, also try to keep 
    // the function argument last, this makes the code
    // more legible when calling with a lambda.
    //
    // you do not know if 'cb', the caller's callable object
    // is copyable or moveable, so you should use perfect 
    // forwarding, that's only (readily) available from a 
    // template.

    template <typename Fn>
    void start(int interval, Fn&& cb)
    {
         stop();  // make sure we're stopped.
         active = true;

         // start the thread, the forward<> of the callback object is 
         // important!
         timer_thread = std::make_unique<std::thread>(
             [this, ms = std::chrono::milliseconds(interval), cb = std::forward<Fn>(cb)]() {
                while (active) // calls atomic<>::load() automatically
                {
                    std::this_thread::sleep_for(ms);
                    if (active)
                        cb();
                }
            });
    }

    // this is where we kill the thread, and wait for it to exit.
    void stop()
    {
        active = false;
        if (timer_thread)
        {
            timer_thread->join();
            timer_thread.reset();
        }
    }

    bool isRunning() const 
    {
        return active;
    }
};

int main()
{
    std::cout << "start\n";

    Timer timer;  // There's absolutely no need to place timer on the heap.
    int n = 4;    // simple countdown to 1 for example.

    timer.start(1000, [&]() { 
         std::cout << "countdown: " << n << '\n';
         if (--n <= 0) 
             timer.stop(); 
     });

    // We should wait for the timer to stop, before exiting the program.
    while (timer.isRunning()) {}

    return 0;
};

字符串

相关问题