gpt4 book ai didi

c++ - 循环定时器线程

转载 作者:太空狗 更新时间:2023-10-29 21:09:59 27 4
gpt4 key购买 nike

我想为循环计时器创建线程池:每 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;
}

但是我的问题:1. 似乎只有一个任务运行,而不是预期的两个。

40557398533888 id: 0    seconds: 1140557390141184 id: 1 seconds: 2
[2019-05-28 11:56:49.770]: 140557398533888
void Foo::test()

[2019-05-28 11:56:50.770]: 140557398533888
void Foo::test()
[2019-05-28 11:56:51.771]: 140557398533888
void Foo::test()
[2019-05-28 11:56:52.771]: 140557398533888
void Foo::test()
[2019-05-28 11:56:53.772]: 140557398533888
void Foo::test()
  1. 经典问题:当我们创建 std::thread 时,它会立即运行,对吗?例如,link .那么,如何改进我的代码以在添加计时器后启动?

编辑 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_ONE 关联的线程完成——在当前情况下永远不会——并且永远不会调用 Foo::getInstance().startTimers(NUM_TWO) .

关于c++ - 循环定时器线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56341917/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com