我正在尝试执行一个必须定期运行2个任务的程序。 也就是说,例如,每10秒运行一次任务1,每20秒运行一次任务2。
我在想的是创建两个线程,每个线程都带有一个计时器。线程1每10秒启动一个任务1的新线程。和线程2每20秒启动一个任务2的新线程。
我的疑问是,如果上一个任务1还没完成,如何启动新任务1?
while (true)
{
thread t1 (task1);
this_thread::sleep_for(std::chrono::seconds(10));
t1.join();
}
我正在尝试这个,但这样它只会在前一个任务完成时启动一个新任务。
编辑:
基本上我想实现一个任务调度程序。 每隔X秒运行一次task1。 每隔Y秒运行一次任务2。 我在考虑这样的事情:
thread t1 (timer1);
thread t2 (timer2);
void timer1()
{
while (true)
{
thread t (task1);
t.detach()
sleep(X);
}
}
与timer2和task2相同
答案 0 :(得分:1)
也许您可以创建一个periodic_task
处理程序,负责每t
秒调度一个任务。然后,您可以从程序中的任何位置启动具有特定功能和持续时间的periodic_task
。
我已经勾勒出了一些东西。一个有效的选择是分离线程并让它永远运行。另一种方法是包括取消以允许父线程取消/加入。我已经包含允许后者的功能(尽管你仍然可以分离/忘记)。
#include <condition_variable>
#include <functional>
#include <iostream>
#include <mutex>
#include <thread>
class periodic_task
{
std::chrono::seconds d_;
std::function<void()> task_;
std::mutex mut_;
std::condition_variable cv_;
bool cancel_{false};
public:
periodic_task(std::function<void()> task, std::chrono::seconds s)
: d_{s}
, task_(std::move(task))
{}
void
operator()()
{
std::unique_lock<std::mutex> lk{mut_};
auto until = std::chrono::steady_clock::now();
while (true)
{
while (!cancel_ && std::chrono::steady_clock::now() < until)
cv_.wait_until(lk, until);
if (cancel_)
return;
lk.unlock();
task_();
lk.lock();
until += d_;
}
}
void cancel()
{
std::unique_lock<std::mutex> lk{mut_};
cancel_ = true;
cv_.notify_one();
}
};
void
short_task()
{
std::cerr << "short\n";
}
void
long_task(int i, const std::string& message)
{
std::cerr << "long " << message << ' ' << i << '\n';
}
int
main()
{
using namespace std::chrono_literals;
periodic_task task_short{short_task, 7s};
periodic_task task_long{[](){long_task(5, "Hi");}, 13s};
std::thread t1{std::ref(task_short)};
std::this_thread::sleep_for(200ms);
std::thread t2{std::ref(task_long)};
std::this_thread::sleep_for(1min);
task_short.cancel();
task_long.cancel();
t1.join();
t2.join();
}
答案 1 :(得分:0)
您希望避免使用thread::join()
,根据定义,等待线程完成。相反,在睡觉前使用thread::detach
,所以不需要等待。
我建议阅读http://www.cplusplus.com/reference/thread/thread/detach/