C++20中的jthread和stop_token
C++20中的jthread和stop_token
前言
C++20中引入了jthread類,相關介紹如下:
The class jthread represents a single thread of execution. It has the same general behavior as std::thread, except that jthread automatically rejoins on destruction, and can be cancelled/stopped in certain situations.
Threads begin execution immediately upon construction of the associated thread object (pending any OS scheduling delays), starting at the top-level function provided as a constructor argument. The return value of the top-level function is ignored and if it terminates by throwing an exception, std::terminate is called. The top-level function may communicate its return value or an exception to the caller via std::promise or by modifying shared variables (which may require synchronization, see std::mutex and std::atomic)
Unlike std::thread, the jthread logically holds an internal private member of type std::stop_source, which maintains a shared stop-state. The jthread constructor accepts a function that takes a std::stop_token as its first argument, which will be passed in by the jthread from its internal stop_source. This allows the function to check if stop has been requested during its execution, and return if it has.
std::jthread objects may also be in the state that does not represent any thread (after default construction, move from, detach, or join), and a thread of execution may be not associated with any jthread objects (after detach).
No two std::jthread objects may represent the same thread of execution; std::jthread is not CopyConstructible or CopyAssignable, although it is MoveConstructible and MoveAssignable.
jthread和thread行為基本一致,可以看做是對thread的包裝,jthread可以在銷燬時實現自動的join,也就是說無需手動呼叫join()函式。並且,jthread提供了一套機制,可以實現執行緒的取消/停止,即本文即將介紹的stop_token(個人感覺和C#的CancellationToken有點相似)。
使用
jthread配合stop_token可以實現執行緒的取消/停止:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int main(int argc, char *argv[]) {
auto f = [](const stop_token &st) { // jthread負責傳入stop_token
while (!st.stop_requested()) { // jthread並不會強制停止執行緒,需要我們依據stop_token的狀態來進行取消/停止操作
cout << "other: " << this_thread::get_id() << "\n";
this_thread::sleep_for(1s);
}
cout << "other thread stopped!\n";
};
jthread jth(f);
cout << "main: " << this_thread::get_id() << "\n";
this_thread::sleep_for(5s);
jth.request_stop(); // 請求停止執行緒,對應的stop_token的stop_requested()函式返回true(注意,除了手動呼叫外,jthread銷燬時也會自動呼叫該函式)
// 我們無需在jthread上呼叫join(),它在銷燬時自動join
}
輸出:
main: 15116
other: 13776
other: 13776
other: 13776
other: 13776
other: 13776
other thread stopped!
參考: