前言
- 什么叫同步
主线程从磁盘读数据,磁盘读取过程中主线程就等着,等数据从磁盘读出来,主线程就能拿到数据了。在从磁盘读取数据的过程中,主线程什么事情都不能干,只能等待。 - 什么叫异步
主线程从磁盘读数据,磁盘读取过程中主线程可以干别的事情,等数据从磁盘读出来,主线程就能拿到数据了。在从磁盘读取数据的过程中,主线程什么事情都可以干,无需等待数据的读取过程。
std::future
首先有个公用的逻辑
#include <iostream>
long long fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
#include <future>
#include <chrono>
int main() {
std::cout << "Main thread started...\n";
// 异步启动 fib(40)
std::future<long long> result = std::async(std::launch::async, fib, 40);
std::cout << "Computing fib(40) in background...\n";
// 主线程可以做别的事
// 这里只是打印点东西
std::this_thread::sleep_for(std::chrono::milliseconds(10));
// 等待结果
long long value = result.get();
std::cout << "fib(40) = " << value << "\n";
return 0;
}
这个能达到我们异步的要求,但是没来一个任务就得启动一个线程。有点浪费。
boost.aio
#include <boost/asio.hpp>
#include <thread>
#include <vector>
#include <chrono>
int main() {
boost::asio::io_context io;
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
work(io.get_executor()); // 防止 run() 提前退出
std::cout << "Main thread started...\n";
// 在后台线程中异步执行 fib(40)
boost::asio::post(io.get_executor(), [n = 40]() {
long long result = fib(n);
std::cout << "fib(" << n << ") = " << result << " [from worker thread]\n";
});
work.reset();
std::cout << "Posted fib(40) to thread pool...\n";
// 启动一个或多个工作线程运行 io_context
std::thread t([&io]() {
io.run();
});
// 主线程也可以干别的事
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::cout << "Main thread is free...\n";
// 等待完成
t.join();
return 0;
}
我们把所有的工作都交给了io_context ,它一方面关联着任务,一方面关联着线程。
上面是一个任务 一个线程,如果是多个线程多个任务呢?
Boost 的多线程模式
#include <boost/asio.hpp>
#include <iostream>
#include <thread>
#include <vector>
long long fib(int n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
int main() {
boost::asio::io_context io;
// 保持 io_context 运行,直到手动 stop()
boost::asio::executor_work_guard<boost::asio::io_context::executor_type>
work(io.get_executor());
std::cout << "Main thread started...\n";
// 提交多个计算任务
for (int i = 0; i < 40; ++i) {
boost::asio::post(io, [n = 35 + i]() {
long long result = fib(n);
std::cout << "fib(" << n << ") = " << result
<< " [thread: " << std::this_thread::get_id() << "]\n";
});
}
std::cout << "Posted tasks to io_context...\n";
work.reset();
// 创建一个“线程池”:比如 4 个线程
const int num_threads = 4;
std::vector<std::thread> threads;
for (int i = 0; i < num_threads; ++i) {
threads.emplace_back([&io]() {
io.run(); // 所有线程共享同一个 io_context
});
}
std::cout << "Main thread is free...\n";
// 等待所有线程完成
for (auto& t : threads) {
t.join();
}
std::cout << "All done.\n";
return 0;
}
如上就是4个线程,处理40个任务。
io_context 就像是一个 集散中心,一方面关联任务,一方面管理线程,这个集散中心的调度工作,对外看就是着线程池的职责。
368

被折叠的 条评论
为什么被折叠?



