Location>code7788 >text

`std::future` - advantages of asynchrony

Popularity:971 ℃/2024-10-07 12:06:11

std::future There are several important advantages to using threads in C++ over using them directly, mainly in the following waysSynchronized Result AcquisitionSimplified code managementandSafer asynchronous task managementetc. The followingstd::future Some of the main advantages of the

1. Automatic results acquisition and synchronization

  • std::future Provides a convenient mechanism to get the return value of an asynchronous task. When we use threads, we usually can't easily get the return value of the thread, and threaded functions that have a return value need to communicate with each other through shared variables, global variables, or other synchronization mechanisms, which makes the code more complex.

  • pass (a bill or inspection etc)std::future, you can easily get the results of asynchronous tasks, and it manages the results of task execution internally and synchronously.

    Example:

    #include <iostream>
    #include <future>
    
    int compute() {
        return 42;
    }
    
    int main() {
        std::future<int> result = std::async(std::launch::async, compute);
        std::cout << "Result: " << () << std::endl; // Automatically waits for the thread to complete and returns the result
        return 0;
    }
    

    In this case.() will wait for the thread to complete and get the return value of the asynchronous task42. This is much simpler than using thread-shared state directly.

2. Simplified code management

  • utilizationstd::thread The thread lifecycle needs to be managed manually, e.g. using thejoin() to wait for the thread execution to complete. Whilestd::future pass (a bill or inspection etc)get() orwait() to wait for the task to be completed.Automatic management synchronizationNo need to manually invoke thejoin()

    When using threads directly:

    #include <iostream>
    #include <thread>
    
    void compute(int &result) {
        result = 42;
    }
    
    int main() {
        int result;
        std::thread t(compute, std::ref(result));
        (); // Must be called manually join() Waiting for the thread to finish
        std::cout << "Result: " << result << std::endl;
        return 0;
    }
    

    Here's how it's going to go through thestd::ref(result) shared data and must manually manage the end of the thread (join()), or else the program will generate an error.

3. Safer asynchronous task management

  • std::future cap (a poem)std::async Asynchronous tasks can be better managed to avoid errors associated with directly manipulating threads. For example, when a thread is not properlyjoin The program may crash whenstd::future will automatically wait for the asynchronous task to complete.

  • If the program exits abnormally or forgets to calljoin()std::thread can cause program interruptions or undefined behavior. Whilestd::future These problems don't occur, it passesget() Automatically wait for asynchronous tasks to complete.

    For example, if you use thestd::threadForget it.join(), the program runs the risk of crashing:

    std::thread t([] { std::this_thread::sleep_for(std::chrono::seconds(1)); });
    // Without (), the program will crash!
    

4. Exception Management

  • std::future can catch exceptions in asynchronous tasks, whereas exception management requires additional work when using threads directly. In thestd::future Middle.get() Not only can you get the result of a task, but you can also throw the exception if it occurs in the task for easy follow-up.

    Example:

    #include <iostream>
    #include <future>
    #include <stdexcept>
    
    int faulty_task() {
        throw std::runtime_error("Something went wrong!");
    }
    
    int main() {
        std::future<int> result = std::async(std::launch::async, faulty_task);
        try {
            int value = (); // Catch an exception here
        } catch (const std::exception& e) {
            std::cerr << "Exception: " << () << std::endl;
        }
        return 0;
    }
    

    Direct usestd::thread when complex mechanisms are required to handle exceptions in tasks, thestd::future Simplifies the process.

5. Delayed start tasks

  • utilizationstd::async cap (a poem)std::future, you can choose whether to start the thread immediately, or delay the execution of the task (inert start). This is accomplished through thestd::async The second parameter of thestd::launch::deferred), can control whether tasks are executed asynchronously or delayed, a flexibility that cannot be easily achieved when using threads directly.

    Inertia Initiation:

    std::future<int> result = std::async(std::launch::deferred, compute); // The task does not execute immediately
    // The task is executed when () is executed.
    

summarize

std::future The main advantage of the

  • Simplifies result acquisition and synchronization operations for asynchronous tasks;
  • Provides better exception management;
  • Avoids the complexity of manually managing thread lifecycles;
  • Provides the flexibility of deferred execution.

In comparison.std::thread Manipulating threads directly, while allowing programmers to control tasks explicitly, in practice this explicit control often leads to complex code management and greater risk of errors, so thestd::future It is a higher level, safer option.