jeudi 12 décembre 2019

Multi-thread console text animations with std::cout

I'm trying to create a function that can animate multiple strings to the console at the same time. By "animate," I mean print a character, wait a specified amount of time, then print the next character, and so on.

This is what I've tried so far:

/**
 @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();
    }
}

This is the driver code for it:

int main()
{
    animate("Hello", 500, false);
    std::cout << '\n' << std::endl;
    animate("Welcome", 400, true);
    std::cout << "\n\nEnd" << std::endl;
}

And this is the output ("Wecome" animates as sluggishly):


Welcome

End

What happened to "Hello"? I'm very new to multi-threading, so a detailed explanation would be very much appreciated. Ideally, what I'd like to happen, is to have "Hello" animating on one line and "Welcome" on the next. Is this possible?

Aucun commentaire:

Enregistrer un commentaire