fifo应该不需要额外的通知渠道,要不然太啰嗦。
只要是读取的一方负责先创建并打开这个fifo对象就行,不然写入的那一方会阻塞在open()。
我现在加个对boost::asio::error::eof的处理,读取的这边发现是这个错误码,就sleep(1),然后继续发async_read_until()请求。
但实际上这个错误码是用来表示对端关掉了fifo,而不是用来表示对端还没打开fifo并写入数据。这点是坑的地方。当然,这两种情况,读取端(server端)可以统一当作一种情况处理,就是对端没数据到达,这倒是没问题。
这个东西的最小demo就是读取方创建、打开fifo,然后调用async_read_until()。不用提供写入方。
g++ 1.cpp -lpthread
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
using namespace boost::asio;
int main() {
try {
// 创建I/O服务对象
io_service io;
// 创建一个FIFO对象
const char* fifo_path = "/tmp/my_fifo";
::unlink(fifo_path);
::mkfifo(fifo_path, 0666);
// 打开FIFO并获取其文件描述符
int fd = ::open(fifo_path, O_RDONLY | O_NONBLOCK);
auto s = boost::asio::posix::stream_descriptor(io, fd);
// 创建一个异步读取对象
boost::asio::streambuf buf;
async_read_until(
s,
buf,
'\n',
[&](const boost::system::error_code& error, std::size_t bytes_transferred) {
if (!error) {
std::istream is(&buf);
std::string line;
std::getline(is, line);
std::cout << "Received: " << line << std::endl;
} else {
std::cout << "Receive error: " << error << std::endl;
}
}
);
// 运行I/O服务对象
io.run();
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
【 在 ziqin 的大作中提到: 】
: 难道是因为A试图读取fifo2时,B还没打开fifo2并写入回应数据?按说不应该有这个同步问题。
: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
: 为什么?从你的描述里,并没有关于,B什么时候通知A可以开始试图读取fifo2的描述
: ...................
--
修改:z16166 FROM 221.218.163.*
FROM 221.218.163.*