每秒执行一次操作的线程

时间:2018-10-03 13:28:54

标签: multithreading c++11 cout

我试图创建一个并发代码,在其中我每秒执行一个函数,此函数将打印一个字符并在该线程上等待一秒钟。我期望的行为是依次打印每个字符,但不会发生,而是打印内部循环执行的所有字符。我不确定这是否与I / O操作有关。

我还尝试创建一个线程数组,其中每个线程都是在内循环执行时创建的,但是即使没有调用join(),行为也会重复。代码可能有什么问题?

以下代码是我尝试执行的操作,我使用时钟查看它是否在等待正确的时间

#include <iostream>
#include <thread>
#include <chrono>
#include <string>

void print_char();

int main() {

    using Timer = std::chrono::high_resolution_clock;
    using te    = std::chrono::duration<double>;
    using s     = std::chrono::seconds;

    te interval;

    for (int i = 0; i < 100; i++) {
        auto  a = Timer::now();
        for (int j = 0; j < i; j++) {

            std::thread t(print_char);
            t.join();
        }
        auto b = Timer::now();
        interval = b-a;

        std::cout << std::chrono::duration_cast<s>(interval).count();
        std::cout << std::endl;
    }

        return 0;
}

void print_char() {
    std::cout << "*";
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

2 个答案:

答案 0 :(得分:2)

  

我期望的行为是依次打印每个字符,但这不会发生,而是打印内部循环执行的所有字符。

您需要刷新输出流才能看到文本:

std::cout << "*" << std::flush;

std::endl包含对std::flush的调用,这就是为什么在内循环完成后看到整行要显示的原因。您的线程确实每秒添加一次'*'个字符,只是在刷新流之后才看到它们被添加。

答案 1 :(得分:1)

考虑代码

std::thread t(print_char);
t.join();

第一行创建并启动线程。第二行立即等待线程结束。这使您的程序 serial 而不是并行的。实际上,这与直接调用该函数而不是创建线程没有什么不同。

如果要使线程并行运行且独立于主线程,则应在线程函数本身中包含循环。也许像

std::atomic<bool> keep_running = true;

void print_char() {
    while (keep_running) {
        std::cout << "*";
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

然后在main函数中,您只需创建线程,然后执行其他操作,直到您希望线程结束即可。

std::thread t(print_char);

// Do something else...

keep_running = false;
t.join();

关于您当前的代码,实际上与

没什么不同
for (int i = 0; i < 100; i++) {
    auto  a = Timer::now();
    for (int j = 0; j < i; j++) {
        print_char();
    }
    auto b = Timer::now();
    interval = b-a;

    std::cout << std::chrono::duration_cast<s>(interval).count();
    std::cout << std::endl;
}