Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 循环计时器线程_C++_Timer_Chrono - Fatal编程技术网

C++ 循环计时器线程

C++ 循环计时器线程,c++,timer,chrono,C++,Timer,Chrono,我想为循环计时器创建线程池:对于每n秒,我们将运行任务 在我的示例中,我们有两个任务。对于每个任务,我将创建一个要运行的线程。我为每个任务添加状态条件,如果状态为false,我们什么也不做。我需要状态来控制定时器,我可以调用定时器启动/停止(对不起,在这段代码中,只有启动功能) 这是我的密码: #include <iostream> #include <list> #include <functional> #include <map> #inc

我想为循环计时器创建线程池:对于每
n
秒,我们将运行任务

在我的示例中,我们有两个任务。对于每个任务,我将创建一个要运行的线程。我为每个任务添加状态条件,如果状态为
false
,我们什么也不做。我需要状态来控制定时器,我可以调用定时器启动/停止(对不起,在这段代码中,只有启动功能)

这是我的密码:

 #include <iostream>
#include <list>
#include <functional>
#include <map>
#include <thread>
#include <chrono>
#include <vector>
#include <mutex>

//using namespace std::chrono_literals;

void print_time()
{
    std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
    std::chrono::system_clock::duration tp = now.time_since_epoch();
    tp -= std::chrono::duration_cast<std::chrono::seconds>(tp);
    std::time_t ttp = std::chrono::system_clock::to_time_t(now);
    tm t = *gmtime(&ttp);

    std::printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u]: ", t.tm_year + 1900,
                t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
                static_cast<unsigned>(tp/std::chrono::milliseconds(1)));
}

typedef std::function<void()> Callback;

enum E_NUM {
    NUM_ONE = 0,
    NUM_TWO
};

class Foo {
    public:
        static Foo& getInstance()
        {
            static Foo instance;
            return instance;
        }

        void init() {
            m_mapThreadStatus[NUM_ONE] = false;
            m_mapThreadStatus[NUM_TWO] = false;
            m_mapCallback[NUM_ONE] = std::bind(&Foo::test, this);
            m_mapCallback[NUM_TWO] = std::bind(&Foo::foo_test, this);
        }

        void addTimer(E_NUM id, int num_seconds) {
            std::thread th ([id, num_seconds] () {
                    std::cout << std::this_thread::get_id() << " id: " << id << "\tseconds: " << num_seconds << std::endl;
                    while (1)
                    {
                        if ( Foo::getInstance().getStatus(id) == true)
                        {
                            Foo::getInstance().callfunctor(id);
                            std::this_thread::sleep_for(std::chrono::seconds(num_seconds));
                        }
                        else
                        {
                        }
                        //std::this_thread::sleep_for(std::chrono::seconds(num_seconds));
                    }
                });
            m_mapThreads[id] = std::move(th);
        }

        void callfunctor(E_NUM id) {
            m_mapCallback[id]();
        }

        void startTimers(E_NUM id) {    
            m_mapThreadStatus[id] = true;
            if (m_mapThreads[id].joinable())
            {
                m_mapThreads[id].join();
            }
        }

        bool getStatus(E_NUM id) { 
            return m_mapThreadStatus[id];}

    private:
        void test() {
            print_time();
            std::cout << std::this_thread::get_id() << std::endl;
            std::cout << "\033[1;31m" << __PRETTY_FUNCTION__ << "\033[0m" << std::endl;
        }
        void foo_test() {
            print_time();
            std::cout << std::this_thread::get_id() << std::endl;
            std::cout << "\033[1;32m" << __PRETTY_FUNCTION__ << "\033[0m" << std::endl;
        }
        Foo() {init();}
        std::map<E_NUM, Callback> m_mapCallback;
        std::vector<std::thread> m_threads;
        std::map<E_NUM, std::thread> m_mapThreads;
        std::map<E_NUM, bool> m_mapThreadStatus;
};

int main()
{
    Foo::getInstance().addTimer(NUM_ONE, 1);
    Foo::getInstance().addTimer(NUM_TWO, 2);
    Foo::getInstance().startTimers(NUM_ONE);
    Foo::getInstance().startTimers(NUM_TWO);
    return 0;
}
  • 经典问题:当我们创建std::线程时,它会立即运行,对吗?例如那么,在添加计时器后,如何改进代码以启动
  • 编辑1: 我在
    Foo
    中添加了函数:

    class Foo {
        ...
        void startTimers() {
            m_mapThreads[NUM_ONE].join();
            m_mapThreads[NUM_TWO].join();
        }
    };
    

    我在main的末尾调用这个函数,它就像一个符咒。谢谢。

    考虑一下您的
    Foo::startTimers
    实现

    void startTimers (E_NUM id)
    {    
        m_mapThreadStatus[id] = true;
        if (m_mapThreads[id].joinable()) {
            m_mapThreads[id].join();
        }
    }
    
    您可以
    启动
    id
    标识的线程,并使用

    m_mapThreadStatus[id] = true;
    
    但是你随后加入了这个线程。最终的结果是,当您启动一个给定的线程时,您的代码将阻塞,直到该线程完成。所以,用

    int main()
    {
        Foo::getInstance().addTimer(NUM_ONE, 1);
        Foo::getInstance().addTimer(NUM_TWO, 2);
        Foo::getInstance().startTimers(NUM_ONE);
        Foo::getInstance().startTimers(NUM_TWO);
        return 0;
    }
    
    那条线

    Foo::getInstance().startTimers(NUM_ONE);
    

    将一直阻止,直到与
    NUM\u ONE
    关联的线程完成(在本例中永远不会完成)和
    Foo::getInstance()。从未调用startTimers(NUM\u TWO)

    感谢您指出我的错误。我忘了主线程将等待连接线程完成。
    Foo::getInstance().startTimers(NUM_ONE);