我在MAC和Linux上的行为不同(ubuntu)当涉及到在asio::posix::stream_descriptor
上执行async_read
/async_write
时。在我的mac上,迭代执行一次(输出iter 13
),然后由于async_read(...)
和async_write(...)
完成句柄从未被调用而挂起在std::future<...>::get()
处的第二次迭代。输出符合预期,即
iter 13
iter 14
有趣的是,如果我切换读/写的顺序,那么它在Mac上可以正常工作。另外,如果我总是读/写最多8192=(1<<13)
字节的数据,那么读/写完成句柄将被调用。stream_descriptor
被分配到的文件是由mkfifo(...)
创建的命名管道。
有没有人知道为什么这是挂在mac上,如果有一个修复?
#include "boost/asio.hpp"
#include <future>
#include <iostream>
#include <cstdio>
int main()
{
using stream_descriptor = boost::asio::posix::stream_descriptor;
// setup the background thread.
boost::asio::io_context ioc;
auto worker = std::make_unique<boost::asio::io_context::work>(ioc);
std::thread thrd([&] {ioc.run(); });
// remove and make the named pipe.
std::string name = "/home/peter/myFifo";
std::remove(name.c_str());
if (mkfifo(name.c_str(), 0666))
throw std::runtime_error("error opening fifo");
// open the two ends of the named pipe. The
// std::async is there since the first will block
// until the second is opened.
int ifd, ofd;
auto f = std::async([&]() {
ifd = open(name.c_str(), O_RDONLY);
});
ofd = open(name.c_str(), O_WRONLY);
f.get();
// create the asio adapter
stream_descriptor in(ioc), out(ioc);
in.assign(ifd);
out.assign(ofd);
// these lines seems to make no difference.
//in.non_blocking(true);
//out.non_blocking(true);
// iterate the the messages sizes that are causing issues.
for (int i = 13; i < 15; ++i)
{
int size = (1 << i);
std::vector<char> buff(size);
boost::asio::mutable_buffer mb(buff.data(), buff.size());
std::promise<boost::system::error_code> p0, p1;
boost::asio::async_read(in, mb,
[&](const boost::system::error_code& ec, size_t bt) {
p1.set_value(ec);
});
boost::asio::async_write(out, mb,
[&](const boost::system::error_code& ec, size_t bt) {
p0.set_value(ec);
});
p0.get_future().get();
p1.get_future().get();
std::cout << "iter " << i << std::endl;
}
// cleanup
worker.reset();
thrd.join();
return 0;
}
1条答案
按热度按时间9lowa7mx1#
ioc.run没有待执行的操作,www.example.com()将退出。如果它退出,将没有异步操作的执行线程。
需要work_guard来防止ioc.run()退出。
可能未使用自动工作保护= asio::使工作保护(ioc);
ioc.run();