我的 C 代碼中有幾個這樣的類:
class ThreadRunner {
public:
void start() {
m_thread = std::thread(&ThreadRunner::runInThread, this);
}
void stop() {
m_terminate = true;
}
~ThreadRunner() {
m_terminate = true;
if (m_thread.joinable()) {
m_thread.join();
}
}
private:
void runInThread() {
size_t i = 0;
while (!m_terminate) {
std::cout << "i: " << i << "\n";
i ;
}
};
std::thread m_thread;
std::atomic<bool> m_terminate{ false };
};
我的一些runInThread函式帶有引數,而有些則沒有。有很多樣板代碼(m_terminate,join)我必須為每個類重復。所有這一切當然是因為我不想終止在解構式內部被呼叫std::thread:
~thread() noexcept {
if (joinable()) {
_STD terminate();
}
}
一位同事制作了一個封裝這個樣板的類。它的作業方式是它有一個virtual void runInThread() = 0方法。所以我的每個類都會繼承這個基類并覆寫這個方法。還有一個隱含的假設,即每個覆寫都會m_terminate偶爾檢查。
我更喜歡使用組合而不是繼承。那是 MyClass 使用 MyThread 不是 MyThreadObject。如何創建一個帶有“函式指標”和任意引數并將它們傳遞給 std::thread 建構式的 start 方法?
如果太麻煩,我想我可以采用我同事的方法。據我了解,Java 有一個必須覆寫的 Runnable 介面void Run()。
如果我要使用std::jthread它應該怎么做?
class ThreadRunner {
public:
void start() {
m_thread = std::jthread(&ThreadRunner::runInThread, this, m_stop_source.get_token());
}
void stop() {
m_stop_source.request_stop();
}
~ThreadRunner() {
stop(); // otherwise ~jthread waits forever for runInThread to finish
}
private:
void runInThread(std::stop_token stoken) {
size_t i = 0;
while (!stoken.stop_requested()) {
std::cout << "i: " << i << "\n";
i ;
}
};
std::jthread m_thread;
std::stop_source m_stop_source;
};
使用 a std::stop_sourceover a 有什么好處std::atomic<bool> m_terminate?
如果我要使用std::async它會怎么做?:
class ThreadRunner {
public:
void start() {
m_future = std::async(std::launch::async, &ThreadRunner::runInThread, this);
}
void stop() {
m_terminate = true;
}
~ThreadRunner() {
stop();
}
private:
void runInThread() {
size_t i = 0;
while (!m_terminate) {
std::cout << "i: " << i << "\n";
i ;
}
};
std::future<void> m_future;
std::atomic<bool> m_terminate{ false };
};
uj5u.com熱心網友回復:
您的std::jthread代碼可以簡化為:
class ThreadRunner {
public:
void start() {
m_thread = std::jthread(&ThreadRunner::runInThread, this);
}
void stop() {
m_thread.request_stop();
}
private:
void runInThread() {
size_t i = 0;
auto stopToken = m_thread.get_stop_token();
while (!stopToken.stop_requested()) {
std::cout << "i: " << i << "\n";
i ;
}
};
std::jthread m_thread;
};
或者由于您的包裝器沒有做太多直接使用std::jthread可能更簡單:
std::jthread thread([](std::stop_token stoken){
size_t i = 0;
while (!stoken.stop_requested()) {
std::cout << "i: " << i << "\n";
i ;
}
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/417317.html
標籤:
下一篇:如何并行寫入容器
