Last active
December 14, 2023 08:59
-
-
Save bwedding/3f67ce5c19feb70aacc45aa3b1111deb to your computer and use it in GitHub Desktop.
Example of C++ std::thread Windows Specific. Creates 30 threads which draw red, white and blue bar graphs moving at separate rates.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <thread> | |
#include <mutex> | |
#include <random> | |
#include <Windows.h> | |
using namespace std::chrono_literals; | |
constexpr int LINE_LEN = 100; | |
bool Running = false; | |
std::mutex ConsoleLock; | |
void SetConsoleColor(WORD color) | |
{ | |
const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | |
SetConsoleTextAttribute(hConsole, color); | |
} | |
void GotoXY(const short x, const short y) | |
{ | |
const COORD pos = { x, y }; | |
const HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE); | |
SetConsoleCursorPosition(output, pos); | |
} | |
void ClearScreen() | |
{ | |
const HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); | |
CONSOLE_SCREEN_BUFFER_INFO csbi; | |
GetConsoleScreenBufferInfo(hConsole, &csbi); | |
const DWORD cellCount = csbi.dwSize.X * csbi.dwSize.Y; | |
const COORD homeCoords = { 0, 0 }; | |
DWORD count; | |
FillConsoleOutputCharacter(hConsole, (TCHAR)' ', cellCount, homeCoords, &count); | |
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, cellCount, homeCoords, &count); | |
SetConsoleCursorPosition(hConsole, homeCoords); | |
} | |
std::string MakeBar(const int value) | |
{ | |
return std::string(value, static_cast<char>(219)); | |
} | |
void ClearCurrentLine() | |
{ | |
std::cout << '\r' << "\x1B[K"; | |
} | |
void DrawGraph(const short line, const int i, const bool down) | |
{ | |
std::lock_guard guard(ConsoleLock); | |
if (down) | |
{ | |
GotoXY(1, line); | |
ClearCurrentLine(); | |
} | |
if (line % 3 == 0) | |
SetConsoleColor(FOREGROUND_RED | FOREGROUND_INTENSITY); // Red | |
else if (line % 3 == 1) | |
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); // White | |
else | |
SetConsoleColor(FOREGROUND_BLUE | FOREGROUND_INTENSITY); // Blue | |
GotoXY(1, line); | |
std::cout << MakeBar(i); | |
} | |
void DrawBar(const short line, const int speed) | |
{ | |
// Wait for the green flag so we all start at the same time | |
while (!Running) | |
std::this_thread::sleep_for(std::chrono::milliseconds(speed)); | |
while (Running) | |
{ | |
for (int i = 1; i < LINE_LEN; i++) | |
{ | |
DrawGraph(line, i, false); | |
std::this_thread::sleep_for(std::chrono::microseconds(speed)); | |
} | |
for (int i = LINE_LEN - 1; i > 0; i--) | |
{ | |
DrawGraph(line, i, true); | |
std::this_thread::sleep_for(std::chrono::microseconds(speed)); | |
} | |
} | |
} | |
void hideCursor() | |
{ | |
const HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); | |
CONSOLE_CURSOR_INFO info; | |
info.dwSize = 100; | |
info.bVisible = FALSE; | |
SetConsoleCursorInfo(consoleHandle, &info); | |
} | |
int main() | |
{ | |
hideCursor(); | |
SetConsoleOutputCP(437); // To make console display extended ASCII | |
std::random_device rd; | |
std::mt19937 eng(rd()); | |
std::uniform_int_distribution<> distr(80, 40000); | |
std::ios_base::sync_with_stdio(false); | |
setvbuf(stdout, nullptr, _IONBF, 0); | |
constexpr int NUM_THREADS = 30; | |
std::vector<std::jthread> threads; | |
threads.reserve(NUM_THREADS); | |
for (int i = 1; i <= NUM_THREADS; ++i) | |
threads.emplace_back(DrawBar, i, distr(eng)); | |
Running = true; | |
// Let them run for a while | |
std::this_thread::sleep_for(8s); | |
// Tell them to stop | |
Running = false; | |
// Wait until they're all finished before we clear screen | |
for (auto& thread : threads) | |
if (thread.joinable()) | |
thread.join(); | |
ClearScreen(); | |
// Reset to default color (usually white) | |
SetConsoleColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment