我试图创建一个并发代码,在其中我每秒执行一个函数,此函数将打印一个字符并在该线程上等待一秒钟。我期望的行为是依次打印每个字符,但不会发生,而是打印内部循环执行的所有字符。我不确定这是否与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));
}
答案 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;
}