再会。
如果我没理解错的话,asio::strand
需要依次进行相关操作。
但是我的操作仍然很混乱。
m 140460063954752
0 140460063950400
1 140460063950400
2 140460055557696
4 140460055557696
3 140460063950400
6 140460063950400
7 140460063950400
8 140460063950400
9 140460063950400
5 140460055557696
问题:我做错了什么?
代码:
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <boost/asio.hpp>
namespace asio = boost::asio;
namespace io = asio;
namespace ip = io::ip;
using namespace std::chrono_literals;
void run_pool(asio::io_context& pool, std::size_t n)
{
std::vector<std::thread> jobs;
jobs.reserve(n);
for (std::size_t i = 0; i < n; ++i)
jobs.emplace_back([&pool]{ pool.run(); });
for (std::size_t i = 0; i < n; ++i)
jobs[i].join();
}
void run_pool(asio::thread_pool& pool, std::size_t /*n*/)
{
pool.wait();
}
int main()
{
using pool_t = std::conditional_t<false, asio::thread_pool, asio::io_context>;
int n_t = static_cast<int>(std::thread::hardware_concurrency());
std::cout << "num threads: " << n_t << std::endl;
pool_t pool{};
std::mutex mtx_io;
auto strand = asio::make_strand(pool);
std::cout << "m " << std::this_thread::get_id() << std::endl;
for (std::size_t n = 0; n < 10; ++n) {
auto token = [n, &mtx_io] {
std::cout << n << " " << std::this_thread::get_id() << std::endl;
};
asio::post(pool, asio::bind_executor(strand, std::move(token)));
}
run_pool(pool, n_t);
return 0;
}
预期行为:n
按顺序输出
当前行为:n
随机显示
试用asio 1.24
和boost::asio 1.82
测试Linux Mint
需要 asio::strand 来避免并发操作。实际上,这是互斥量的类比——在整个线程池中,任何时候与一个链相关的操作将由不超过一个线程执行。它不影响哪些线程以及以什么顺序执行这些操作。在操作本身内使用互斥锁的优势在于,处理程序可以解析属于其他链的操作,而不是被锁定的互斥锁闲置。