C++ 20 – <stop_token> Header
C++20 has introduced the <stop_token> Header, presenting an alternative method for canceling asynchronous operations. A new class std::stop_token is provided by the <stop_token> header that allows for seamless communication of a termination request between two threads.
In this article, we will discuss the basics of <stop_token> and how to use it in C++20.
Classes in <stop_token> Header
The <stop_token> header file contains 2 main classes which are:
- stop_source: The stop_source class is used to request cancellation.
- stop_token: The stop_token class is used to check if there is a need to issue the cancellation.
std::stop_token Class
The std::stop_token is a class that provides a way to call off asynchronous operation requests. It is equivalent to a token that can be transferred through different program fragments, providing the ability to notify about the cancellation of an ongoing process. Interestingly, the std::stop_token objects are highly convenient as they can be easily moved and copied, without adding much burden to the system’s processing.
Syntax
stop_token token_name = token;
std::stop_token Member Methods
The two primary functions of the std::stop_token class are:
- stop_requested(): This function responds with a value of true when a cancellation request has been made, otherwise, it returns false.
- stop_possible(): This function returns true if the related std::stop_source object can be utilized to request a cancellation, otherwise it returns false.
Examples of stop_token
Example 1
In the below code, we will make use of the above syntax to demonstrate the use of the <stop_token> Header.
C++
// C++ Program to illustrate the stop_token #include <chrono> #include <iostream> #include <stop_token> #include <thread> using namespace std; // callable function for thread void worker(stop_token stopToken) { // checking if the stop request is made using // stop_request method of stop_token class while (!stopToken.stop_requested()) { cout << "Working..." << endl; this_thread::sleep_for(chrono::seconds(1)); } cout << "Cancelled." << endl; } // driver code int main() { // creating stop_source object stop_source stopSource; // creating stop_token object stop_token stopToken = stopSource.get_token(); // starting thread thread t(worker, stopToken); this_thread::sleep_for(chrono::seconds(5)); // requesting stop stopSource.request_stop(); t.join(); return 0; } |
Output
Working... Working... Working... Working... Working... Cancelled.
Explanation: In this example, A novel std::stop_source is established along with its associate, a std::stop_token. After passing the stopToken object as a parameter to the worker function, a new thread is initiated.
The worker function employs the stop_requested() function to verify if there are any cancellation petitions. After waiting for approximately 5 seconds, it seeks for cancellation by requesting the stopSource object to stop via the request_stop() function. Finally, we join the thread and exit the program.
Example 2
C++
// C++ program to illustrate the use of stop_token #include <chrono> #include <iostream> #include <stop_token> #include <thread> using namespace std; // thread callable class Worker { public : void run(stop_token stopToken) { while (!stopToken.stop_requested()) { cout << "Working..." << endl; this_thread::sleep_for(chrono::seconds(1)); } cout << "Cancelled." << endl; } }; // driver code int main() { // creating stop_source and stop_token objects stop_source stopSource; stop_token stopToken = stopSource.get_token(); // initializing thread Worker worker; thread t(&Worker::run, &worker, stopToken); this_thread::sleep_for(chrono::seconds(5)); // requesting stop after 5 seconds stopSource.request_stop(); t.join(); return 0; } |
Output
Working... Working... Working... Cancelled.
Explanation: In this example, Upon defining a class named Worker, we create a function run that expects a stopToken of std::type to be passed as a parameter. We initiate a thread to run the Worker object’s run method, providing the stopToken object as an argument. The run method frequently checks the stop_requested() function of the stopToken object to ensure that the cancellation requests are taken into consideration.
Advantages of stop_token
The advantages of using stop_token are as follows:
- Efficient and lightweight: It provides a lightweight and efficient way of canceling asynchronous operations. The std::stop_token class is lightweight and can be copied and moved efficiently.
- More elegant and thread-safe: It avoids the need for manual cancellation flags and provides a more elegant and thread-safe way of canceling operations. This makes it easier to write robust and efficient code.
- Interoperability: It is designed to be interoperable with other C++20 concurrency features such as coroutines and futures. This makes it easier to write complex concurrent programs.
- Scalable and flexible: It is scalable and flexible, making it suitable for a wide range of applications, from simple programs to complex systems. It allows for fine-grained control over the cancellation of asynchronous operations.
- Standardized: It is part of the C++20 standard library, which means that it is widely available and supported by many compilers and tools.
Contact Us