Open In App

C++ 20 – <stop_token> Header

Last Updated : 06 Jun, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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:

  1. stop_source: The stop_source class is used to request cancellation.
  2. 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.


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads