前言:這是我第一次嘗試用任何語言撰寫多執行緒程式。我以前沒有使用 std::thread 或描述多執行緒程式的經驗。如果您需要更多資訊來回答這個問題,或者我是否可以改寫任何內容以使我的問題更清楚,請告訴我。
假設我有一個簡單的影片函式animate,它(現在)無限期地運行;和另一個函式task,它代表一些要執行的任意代碼。
#include <string>
// a simple rotating stick animation: | -> / -> - -> \
void animate()
{
std::string syms = "|/-\\";
while (true)
{
for (unsigned int ii = 0; ii < syms.length(); ii)
{
std::cout << syms[ii];
std::cout << std::string(1, '\b');
}
}
}
// arbitrary function
void task()
{
// code to do something else goes here
}
int main (int argc, char* argv[])
{
// execute task and animate at the same time;
// return from animate once task has completed
return 0;
}
我如何使用std::thread(或其他一些標頭/庫)來允許task和animate相互通信,以便task在“后臺”運行并animate運行直到task完成?
uj5u.com熱心網友回復:
我已經獲取了您的示例代碼,并嘗試使用std::thread. 我已經添加了一些行內評論來解釋發生了什么。如果有不清楚的地方,或者我弄錯了,請隨時在評論中提問。
我想強調的是,此示例僅用于std::thread在玩具示例中創建和加入單獨的執行緒。它不會以正確的方式在執行緒之間同步共享資料。MT 環境中的共享資料是事情變得棘手的地方,最糟糕的是它會產生一些最難除錯的錯誤。這就是為什么書籍和作業示例對于任何實質性的多執行緒程式都很重要的原因。
#include <string>
#include <thread>
#include <chrono>
#include <iostream>
// a simple rotating stick animation: | -> / -> - -> \
//
void animate(bool * should_animate)
{
// Using this namespace lets us use the "100ms" time literal in the sleep_for() function argument.
using namespace std::chrono_literals;
std::string syms = "|/-\\";
while (*should_animate)
{
for (unsigned int ii = 0; ii < syms.length(); ii)
{
std::cout << syms[ii];
std::cout << std::string(1, '\b');
// I had to flush cout so that the animation would show up
std::cout.flush();
// I added some delay here so that the animation is more visible
std::this_thread::sleep_for(100ms);
}
}
}
// arbitrary function
void task()
{
using namespace std::chrono_literals;
// I have this thread waiting for 2 seconds to simulate a lot of work being done
std::this_thread::sleep_for(2s);
}
int main (int argc, char* argv[])
{
// This line creates a thread from the animate() function
// The std::thread constructor is flexible, in that it can take a function with any number and type of arguments and
// make a thread out of it
// Once the thread is created, it gets sent to the operating system for scheduling right away in a separate thread
// I'm passing in a pointer to `should_animate` to use that value as a basic way to communicate to the animate thread to signal when it should stop running.
// I'm doing this to keep the example simple, but I stress that this isn't a good idea for larger scale programs
// Better to use propper signals or event queues
bool should_animate = true;
std::thread thread_animate(animate, &should_animate);
// This line creates a thread for the worker task
// That separate thread can be referenced by tis std::thread object
// Once the functions finish running, the thread associated with it is "joined"
std::thread thread_task(task);
// 'join' pauses the main thread to wait for the associated thread to finish running in the background.
thread_task.join();
// By this point in the program, the `task()` function has finished running, so we can flag
// the animate task to finish running so its thread can be joined
should_animate = false;
// Wait for the animate thread to get the message and finish
thread_animate.join();
std::cout << "Done!" << std::endl;
return 0;
}
如果你想更進一步,這里有一些我推薦的鏈接。
- 這是我在谷歌第一頁能找到的最好的教程(大多數結果似乎很糟糕)。似乎是一個很好的起點https://solarianprogrammer.com/2011/12/16/cpp-11-thread-tutorial/
- cppreference 是我所知道的最好的 C 參考網站,而且我通常一整天都至少有一個標簽。因為是參考,很難直接挖掘。此頁面的每個部分標題都涵蓋一個多執行緒主題。“執行緒”和“互斥”是 MT 中最常用的東西。https://en.cppreference.com/w/cpp/thread
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/473954.html
上一篇:如何圍繞給定軸旋轉bvh運動?
下一篇:不使用z-index的卡片影片
