启动多个线程的C ++线程

时间:2016-07-01 18:57:30

标签: c++ multithreading

我正在尝试执行一个必须定期运行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相同

2 个答案:

答案 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/