C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > std::funture和std::promise

C++中的std::funture和std::promise实例详解

作者:vegetablesssss

在线程池中获取线程执行函数的返回值时,通常使用 std::future 而不是 std::promise 来传递返回值,这篇文章主要介绍了C++中的std::funture和std::promise实例详解,需要的朋友可以参考下

std::funture和std::promise

#include <iostream>
#include <thread>
#include <future>
void calculateResult(std::promise<int>& promiseObj) {
	// 模拟耗时计算
	std::this_thread::sleep_for(std::chrono::seconds(2));
	// 设置结果到 promise 中
	promiseObj.set_value(42);
}
int main() {
	// 创建一个 promise 对象
	std::promise<int> promiseObj;
	// 获取与 promise 关联的 future
	std::future<int> futureObj = promiseObj.get_future();
	// 启动一个新的线程执行计算
	std::thread workerThread(calculateResult, std::ref(promiseObj));
	// 在主线程中等待任务完成,并获取结果
	int result = futureObj.get();
	std::cout << "Result: " << result << std::endl;
	// 等待工作线程结束
	workerThread.join();
	return 0;
}

使用future和promise可以获取到线程执行函数的结果,类似C#实现

#include <iostream>
#include <thread>
#include <future>
#include <vector>
#include <functional>
#include <queue>
class ThreadPool {
public:
    explicit ThreadPool(size_t numThreads) : stop(false) {
        for (size_t i = 0; i < numThreads; ++i) {
            threads.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(mutex);
                        condition.wait(lock, [this] { return stop || !tasks.empty(); });
                        if (stop && tasks.empty()) {
                            return;
                        }
                        task = std::move(tasks.front());
                        tasks.pop();
                    }
                    task();
                }
                });
        }
    }
    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(mutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread& thread : threads) {
            thread.join();
        }
    }
    template <class F, class... Args>
    auto enqueue(F&& f, Args&&... args) -> std::future<typename std::result_of<F(Args...)>::type> {
        using return_type = typename std::result_of<F(Args...)>::type;
        auto task = std::make_shared<std::packaged_task<return_type()>>(
            std::bind(std::forward<F>(f), std::forward<Args>(args)...)
        );
        std::future<return_type> result = task->get_future();
        {
            std::unique_lock<std::mutex> lock(mutex);
            if (stop) {
                throw std::runtime_error("enqueue on stopped ThreadPool");
            }
            tasks.emplace([task]() { (*task)(); });
        }
        condition.notify_one();
        return result;
    }
private:
    std::vector<std::thread> threads;
    std::queue<std::function<void()>> tasks;
    std::mutex mutex;
    std::condition_variable condition;
    bool stop;
};
int calculateResult() {
    // 模拟耗时计算
    std::this_thread::sleep_for(std::chrono::seconds(2));
    return 42;
}
int main() {
    ThreadPool pool(4);
    std::future<int> futureObj = pool.enqueue(calculateResult);
    int result = futureObj.get();
    std::cout << "Result: " << result << std::endl;
    return 0;
}

在线程池中获取线程执行函数的返回值时,通常使用 std::future 而不是 std::promise 来传递返回值。这是因为线程池内部已经管理了任务的执行和结果的传递,你只需要将任务提交给线程池,并使用 std::future 来获取结果。

线程池内部一般会使用一个任务队列来存储待执行的任务,并使用一个线程池管理器来调度任务的执行。当你向线程池提交任务时,线程池会选择一个空闲的线程来执行任务,并将结果存储在与任务关联的 std::future 对象中。

扩展:C# 异步

首先说几个关键词:

async:修饰方法,表明该方法是异步的
Task:异步任务,可以作为异步方法的返回值
await:等待异步方法执行完成,只能在异步方法中使用
TaskCompletionSource:可通过SetResult方法来设置异步的结果

using System;
using System.Threading.Tasks;
class Program
{
    static async void AsyncMethod()
    {
        await Task.Run(() =>
        {
            Console.WriteLine("耗时操作");
        });
        await AsyncTaskCompletion();
    }
    static async Task<int> AsyncTaskCompletion()
    {
        Console.WriteLine("AsyncTaskCompletion Start");
        TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
        // 模拟异步操作
        await Task.Delay(3000).ContinueWith(task =>
        {
            if (task.Exception != null)
            {
                tcs.SetException(task.Exception);
            }
            else
            {
                // 设置异步操作的结果
                tcs.SetResult(42);
            }
        });
        Console.WriteLine("AsyncTaskCompletion END");
        return await tcs.Task;
    }
    static void Main()
    {
        Console.WriteLine("Main Start");
        AsyncMethod(); 
        Console.WriteLine("Main END");
        Console.ReadLine();
    }
}

main方法中执行一个返回值为空的异步方法AsyncMethod,在AsyncMethod可以执行各种耗时操作而不影响main方法执行。
在AsyncTaskCompletion方法中等待tcs.SetResult方法执行后才会返回,可用于在回调函数中设置结果。

到此这篇关于C++中的std::funture和std::promise实例详解的文章就介绍到这了,更多相关std::funture和std::promise内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文