async、future、shared_future、promise、packaged_task练习题目

练习题 1: 使用 std::futurestd::async

编写一个程序,使用 std::async 启动一个异步任务,该任务计算两个整数的和。主线程等待任务完成并输出结果。

题目要求:
  • 使用 std::async 创建异步任务。

  • 主线程获取任务的结果并打印。

#include<iostream>
#include<future>
#include<thread>
using namespace std;

int compute_sum(int x, int y) {
    cout << "子线程开始计算.." << endl;
    return x + y;
}

int main() {
    cout << "主线程开始..." << endl;
    int x = 1, y = 2;
    future<int> fut = async(launch::async, compute_sum, x, y);

    int result = fut.get();
    cout << "主线程得到答案:" << result << endl;
    return 0;
}

练习题 2: 使用 std::shared_future

编写一个程序,创建一个异步任务,计算一个整数的平方,并使用 std::shared_future 在多个线程中共享计算结果。

题目要求:
  • 使用 std::async 启动一个计算平方的任务。

  • 使用 std::shared_future 在多个线程中共享该结果。

  • 每个线程打印结果。

#include<iostream>
#include<future>
#include<thread>
#include<vector>
#include<mutex>
using namespace std;

mutex mtx;

int compute_sqr(int x) {
    lock_guard<mutex> lock(mtx);
    cout << "现在正在计算的线程是:" << this_thread::get_id() << endl;
    return x * x;
}

int main() {
    cout << "主线程开始..." << endl;
    future<int> fut = async(launch::async, compute_sqr, 5);

    shared_future<int> shared_fut = fut.share();

    vector<thread> threads;
    for (int i = 0; i < 3; i++) {
        threads.push_back(thread([&shared_fut] {
            lock_guard<mutex> lock(mtx);
            cout << "现在运行的线程是:" << this_thread::get_id() << " 获得sqr=" << shared_fut.get() << endl;
            }));
    }

    for (auto& t : threads) {
        t.join();
    }

    cout << "主线程结束" << endl;
    return 0;
}

这里对于shared_future的理解更加深刻了,async线程只会运行一次,shared_future使得结果可以让不同线程多次获取


练习题 3: 使用 std::packaged_taskstd::thread

编写一个程序,使用 std::packaged_task 包装一个函数,该函数计算给定整数的阶乘。使用 std::thread 来执行任务,并获取结果。

题目要求:
  • 使用 std::packaged_task 包装一个计算阶乘的函数。

  • 使用 std::thread 来执行这些任务。

  • 获取并打印结果。

使用ref,引用传递,需要注意的就是资源是否会释放问题,这里使用的get,join都是阻塞,所以不会有问题

#include<iostream>
#include<future>
#include<thread>
using namespace std;

mutex mtx;

int compute_factor(int x) {
    int res = 1;
    for (int i = 1; i <= x; i++)res *= i;
    return res;
}

int main() {
    cout << "主线程开始..." << endl;
    packaged_task<int(int)> task(compute_factor);

    int x = 5;
    thread t(ref(task), x);
    future<int> fut = task.get_future();

    cout << x << "的阶乘=" << fut.get() << endl;

    t.join();

    cout << "主线程结束" << endl;
    return 0;
}

使用move,要在thread移动前获取task.get_future,否则task资源已经被转移了,无法获取

#include<iostream>
#include<future>
#include<thread>
using namespace std;

int compute_factor(int x) {
    int result = 1;
    for (int i = 1; i <= x; ++i) {
        result *= i;
    }
    return result;
}

int main() {
    cout << "主线程开始..." << endl;
    packaged_task<int(int)> task(compute_factor);
    future<int> fut = task.get_future();

    int x = 5;
    thread t(move(task), x);

    cout << x << "的阶乘=" << fut.get() << endl;
    t.join();

    cout << "主线程结束" << endl;
    return 0;
}

练习题 4: 使用 std::promisestd::future

编写一个程序,使用 std::promisestd::future 在两个线程之间传递数据。一个线程将结果设置到 promise 中,另一个线程获取结果。

题目要求:
  • 创建一个 std::promise 对象。

  • 在一个线程中使用 set_value 设置结果。

  • 在另一个线程中使用 future.get() 获取并打印结果。

引用版本

#include<iostream>
#include<future>
#include<thread>
#include<vector>
using namespace std;


int compute_add(promise<int>& pro,int x,int y) {
    int res = x + y;
    pro.set_value(res);
    cout << "和线程" << this_thread::get_id() << " 计算结果=" << res << endl;
    return res;
}

int compute_sqr(int x) {
    int res = x * x;
    cout << "平方线程" << this_thread::get_id() << " 计算结果=" << res << endl;
    return res;
}

int main() {
    cout << "主线程开始..." << endl;
    
    promise<int> pro;
    thread t1(compute_add, ref(pro), 3, 4);

    future<int> fut = pro.get_future();

    thread t2(compute_sqr, fut.get());

    t1.join();
    t2.join();
    cout << "主线程结束" << endl;
    return 0;
}

移动版本

  • promise<int>&& pro 的移动:通过 move(pro),将 promise 移动到 t1 线程中。这确保了在加法线程计算后,promise 的值会被正确设置。

  • future 传递到线程中compute_sqr 函数现在接收 future<int>& fut,并在里面调用 fut.get() 获取加法结果。这样就不需要在主线程中调用 fut.get(),避免了重复调用 get() 的问题。

#include<iostream>
#include<future>
#include<thread>
#include<vector>
using namespace std;

int compute_add(promise<int>&& pro, int x, int y) {
    int res = x + y;
    pro.set_value(res);
    cout << "和线程 " << this_thread::get_id() << " 计算结果=" << res << endl;
    return res;
}

int compute_sqr(future<int>& fut) {
    int res = fut.get(); // 获取加法结果并计算平方
    cout << "平方线程 " << this_thread::get_id() << " 计算结果=" << res * res << endl;
    return res * res;
}

int main() {
    cout << "主线程开始..." << endl;

    promise<int> pro;
    future<int> fut = pro.get_future(); // 获取与 promise 相关的 future

    thread t1(compute_add, move(pro), 3, 4); // 将 promise 移动到线程中
    thread t2(compute_sqr, ref(fut)); // 将 future 传递给平方线程

    t1.join();
    t2.join();

    cout << "主线程结束" << endl;
    return 0;
}


练习题 5: 任务队列与 std::packaged_task

创建一个任务队列,队列中的每个任务计算不同的整数的平方。使用 std::packaged_task 将每个计算包装成任务,并使用线程池执行这些任务。最终获取并输出所有任务的结果。

题目要求:
  • 使用 std::packaged_task 创建多个任务,每个任务计算不同整数的平方。

  • 将任务存储在容器中,并使用线程池来执行。

  • 最终收集并输出每个任务的结果。

#include<iostream>
#include<future>
#include<thread>
#include<vector>
using namespace std;



int compute_sqr(int x) {
    int res = x * x;
    return res;
}

int main() {
    cout << "主线程开始..." << endl;
    vector<packaged_task<int(int)>> tasks;
    vector<future<int>> futures;


    for (int i = 0; i < 10; i++) {
        tasks.push_back(packaged_task(compute_sqr));
        futures.push_back(tasks[i].get_future());
    }

    vector<thread> threads;
    for (int i = 0; i < 10; i++) {
        threads.push_back(thread(move(tasks[i]),i+1));
    }

    for (auto& fut : futures) {
        cout << fut.get() << endl;
    }

    for (auto& t : threads) {
        t.join();
    }



    cout << "主线程结束" << endl;
    return 0;
}


练习题 6: 使用 std::future 和超时

编写一个程序,使用 std::future 启动一个异步任务,计算一个大数的平方,主线程在 1 秒钟后检查任务是否完成。如果任务未完成,则打印 “任务超时”。

题目要求:
  • 启动一个计算大数平方的异步任务。

  • 使用 std::future::wait_for 设置超时,如果任务未在超时时间内完成,则打印 “任务超时”。

#include<iostream>
#include<future>
#include<thread>
#include<vector>
using namespace std;



int compute_sqr(int x) {
    this_thread::sleep_for(2s);
    int res = x * x;
    return res;
}

int main() {
    cout << "主线程开始..." << endl;
    
    future<int> fut = async(launch::async, compute_sqr, 5);

    future_status fut_status = fut.wait_for(1s);

    if (fut_status == future_status::timeout) {
        cout << "任务超时" << endl;
    }
    else {
        cout << "任务完成,结果=" << fut.get() << endl;
    }

    cout << "主线程结束" << endl;
    return 0;
}


练习题 7: 使用 std::future 和异常处理

编写一个程序,使用 std::async 启动一个异步任务,该任务计算一个数字的倒数。如果输入为零,则抛出异常并在主线程中捕获该异常。

题目要求:
  • 使用 std::async 启动异步任务计算倒数。

  • 如果输入为零,则抛出异常。

  • 在主线程中捕获并打印异常信息。

#include<iostream>
#include<future>
#include<thread>
#include<vector>
using namespace std;



double compute_reciprocal(double x) {
    if (x == 0)throw invalid_argument("倒数不能为0!");
    return 1.0 / x;
}

int main() {
    cout << "主线程开始..." << endl;
    
    double x = 0;
    future<double> fut = async(launch::async, compute_reciprocal, x);

    try {
        cout << x << "的倒数是" << fut.get() << endl;
    }catch(const invalid_argument &e){
        cout << e.what() << endl;
    }

    cout << "主线程结束" << endl;
    return 0;
}


练习题 8: 使用 std::shared_future 和多个线程

编写一个程序,启动一个异步任务,计算 100 到 200 之间所有数字的和。多个线程使用 std::shared_future 获取该任务的结果并输出结果。

题目要求:
  • 使用 std::async 启动异步任务,计算和。

  • 使用 std::shared_future 将结果共享给多个线程。

  • 每个线程输出结果。

#include<iostream>
#include<future>
#include<thread>
#include<vector>
using namespace std;



int compute_sum() {
    int res = 0;
    for (int i = 100; i <= 200; i++)res += i;
    return res;
}

int main() {
    cout << "主线程开始..." << endl;
    
    future<int> fut = async(launch::async, compute_sum);
    shared_future<int> shared_fut = fut.share();

    vector<thread> threads;
    for (int i = 0; i < 5; i++) {
        threads.push_back(thread([&shared_fut] {cout << "线程" << this_thread::get_id() << "拿到共享结果为=" << shared_fut.get() << endl; }));
    }

    for (auto& t : threads) {
        t.join();
    }

    cout << "主线程结束" << endl;
    return 0;
}


练习题 9: 使用 std::packaged_task 和多线程计算任务

编写一个程序,创建一个 std::packaged_task 对象,包装一个计算两个整数最大公约数(GCD)的函数。然后使用多个线程分别计算不同整数对的 GCD,获取结果并输出。

题目要求:
  • 使用 std::packaged_task 包装计算 GCD 的任务。

  • 使用多个线程计算不同整数对的 GCD。

  • 输出每对整数的 GCD 结果。

#include<iostream>
#include<future>
#include<thread>
#include<vector>
using namespace std;

int compute_gcd(int a, int b) {
    return b == 0 ? a : compute_gcd(b, a % b);
}

int main() {
    cout << "主线程开始..." << endl;

    vector<thread> threads;
    vector<future<int>> futures;

    // 直接在循环中创建任务并传递给线程
    for (int i = 0; i < 5; i++) {
        packaged_task<int(int, int)> task(compute_gcd);
        futures.push_back(task.get_future());
        threads.push_back(thread(move(task), i * 10, i * 5));
    }

    // 等待所有线程并获取结果
    for (auto& fut : futures) {
        cout << "公约数为=" << fut.get() << endl;
    }

    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }

    cout << "主线程结束" << endl;
    return 0;
}



练习题 10: 使用 std::promise 实现任务通知

编写一个程序,创建一个 std::promise 对象,主线程通过 promise 设置一个值,另一个线程等待该值并输出通知。

题目要求:
  • 使用 std::promise 设置一个整数值。

  • 主线程通过 promise 设置值,另一个线程获取并输出该值。

#include <iostream>
#include <future>
#include <thread>
#include <chrono>
using namespace std;

void task(promise<int>& prom) {
    // 模拟一个耗时操作
    this_thread::sleep_for(2s);
    prom.set_value(100); // 设置任务完成的结果
}

int main() {
    cout << "主线程开始..." << endl;

    promise<int> prom;
    future<int> fut = prom.get_future();

    thread t(task, ref(prom)); // 启动一个线程,模拟任务执行

    // 主线程等待任务完成并获取结果
    cout << "主线程等待任务完成..." << endl;
    cout << "Received value: " << fut.get() << endl; // 获取并打印结果

    t.join(); // 等待子线程完成
    cout << "主线程结束" << endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值