[英]Multi-thread console text animations with std::cout
我正在嘗試創建一個可以同時將多個字符串動畫到控制台的函數。 “動畫”是指打印一個字符,等待指定的時間,然后打印下一個字符,依此類推。
這是我迄今為止嘗試過的:
/**
@param msg Message to animate
@param sleep_time Time to wait between each letter
@param wait Whether or not to wait for the current thread to join before returning
*/
void animate(const std::string& msg, const unsigned long long sleep_time, const bool wait = true)
{
const std::atomic<std::chrono::milliseconds> t_sleep_time =
std::chrono::milliseconds(sleep_time);
std::stringstream msg_strm;
msg_strm << msg;
std::thread animate_thread([&msg_strm, &t_sleep_time]() -> void
{
char letter;
while ((letter = msg_strm.get()) != EOF)
{
std::cout << letter << std::flush;
std::this_thread::sleep_for(t_sleep_time.load());
}
return;
});
if (wait)
{
animate_thread.join();
}
else
{
animate_thread.detach();
}
}
這是它的驅動程序代碼:
int main()
{
animate("Hello", 500, false);
std::cout << '\n' << std::endl;
animate("Welcome", 400, true);
std::cout << "\n\nEnd" << std::endl;
}
這是輸出(“Wecome”動畫緩慢):
Welcome
End
“你好”怎么了? 我對多線程很陌生,因此非常感謝詳細的解釋。 理想情況下,我希望發生的事情是在一行上播放“你好”動畫,在下一行播放“歡迎”。 這可能嗎?
首先, msg_strm
存在於堆棧中,因此您無法將其按值傳遞給線程,因為它超出了范圍,這就是為什么最有可能的Hello
沒有顯示的原因。 您還有另一個問題是您正在調用detach
因此程序可能會在第一個線程完成之前退出。
為了實現您的目標,我建議使用ANSI escape codes
。 因此,以下內容可能不適用於所有命令提示符。 另請注意,如果您分步打印,則std::cout
不是線程安全的。
#include <atomic>
#include <iostream>
#include <string>
#include <thread>
std::atomic<int> g_lines = 1;
std::thread animate(const std::string& msg, const unsigned long long sleep_time)
{
// NOTE: `[=]` means capture all variables used by value. Note that globals
// are not captured. Also note that capture by value is needed because
// `msg` can go out-of-scope.
return std::thread([=] {
auto line = g_lines++;
for (size_t column = 1; column <= msg.size(); column++)
{
// using `ANSI escape codes` move the cursor to the correct
// position; \x1B[{line};{column}H
std::cout << "\x1B[" + std::to_string(line) + ";"
+ std::to_string(column) + "H" + msg[column - 1];
std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time));
}
});
}
int main()
{
auto t1 = animate("Hello", 500);
auto t2 = animate("Welcome", 400);
// you need to join all threads else if you call detach, the program might
// exit before all threads finish.
t1.join();
t2.join();
std::cout << "\n\nEnd" << std::endl;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.