Asynchronous 异步读取inotify描述符失败
我正在基于源代码编写一个监控文件程序: 我的程序使用boost::asio::stream_descriptor::async_read_some()从inotify描述符进行异步读取 我的代码如下: 建造商:Asynchronous 异步读取inotify描述符失败,asynchronous,boost-asio,inotify,file-monitoring,Asynchronous,Boost Asio,Inotify,File Monitoring,我正在基于源代码编写一个监控文件程序: 我的程序使用boost::asio::stream_descriptor::async_read_some()从inotify描述符进行异步读取 我的代码如下: 建造商: void init(){ int fd = inotify_init1(IN_NONBLOCK); int wd = inotify_add_watch(fd_, "./test.txt", IN_ALL_EVENTS); stream_.reset(new bo
void init(){
int fd = inotify_init1(IN_NONBLOCK);
int wd = inotify_add_watch(fd_, "./test.txt", IN_ALL_EVENTS);
stream_.reset(new boost::asio::posix::stream_descriptor(io_service_, fd_)));
}
异步读取:
template<typename Monitor_Handler>
void async_monitor(Monitor_Handler handler) {
stream_->async_read_some(boost::asio::buffer(buffer_),
boost::bind(&monitor::handle_monitor<Monitor_Handler>,
shared_from_this(), boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred, handler));
}
模板
无效异步\u监视器(监视器处理程序){
流->异步读取(boost::asio::buffer(buffer)、,
boost::bind(&monitor::handle\u monitor、,
共享\u来自\u this(),boost::asio::placeholders::error,
boost::asio::占位符::字节(已传输,处理程序));
}
处理程序:
template<typename Monitor_Handler>
void handle_monitor(const boost::system::error_code &ec,
std::size_t bytes_transferred, Monitor_Handler handler) {
//process buffer
async_monitor(handler);
}
模板
无效句柄监视器(常量boost::系统::错误代码和ec,
std::大小\u t字节\u传输,监视器\u处理程序){
//进程缓冲区
异步监视器(处理器);
}
错误在于,对于受监控文件中的第一次更改,第一次调用handle_monitor多次(多个事件,如MODIFY、ACCESS、OPEN…)。在异步读取之后,会再次调用某个方法,但我再也没有收到任何信号(不再调用handle\u监视器)
但是,当我尝试重置inotify描述,并再次读取受监视的文件==>它工作时,会调用handle_监视器来对这些受监视的文件进行新的更改
修改代码:
template<typename Monitor_Handler>
void handle_monitor(const boost::system::error_code &ec,
std::size_t bytes_transferred, Monitor_Handler handler) {
//process buffer
async_monitor(handler);
init();//for resetting the inotify desciptor
}
模板
无效句柄监视器(常量boost::系统::错误代码和ec,
std::大小\u t字节\u传输,监视器\u处理程序){
//进程缓冲区
异步监视器(处理器);
init();//用于重置inotify描述符
}
你们能帮我解释一下吗????我渴望得到你的答案……。我觉得这很可疑
void init(){
int fd = inotify_init1(IN_NONBLOCK);
int wd = inotify_add_watch(fd_, "./test.txt", IN_ALL_EVENTS);
stream_.reset(new boost::asio::posix::stream_descriptor(io_service_, fd_)));
}
您应该使用从notify_init1()
返回的值创建stream_描述符
,该值将是fd
,而不是fd
。我假设fd\uu
是类成员,可能未初始化或初始化为0
\include
#include <string>
#include <algorithm>
#include <cstring>
#include <assert.h>
#include <sys/signalfd.h>
#include <sys/inotify.h>
#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <iostream>
//compile with
//-------------
//g++ -std=c++0x -g -I/usr/local/include -I/home/rk/Downloads/websocketpp/src asio.cc -L/home/rk/Downloads/websocketpp -L/usr/local/lib/ -lwebsocketpp -lboost_thread -lboost_exception -lboost_date_time -lboost_regex -lboost_system -o asio
static int inotifyFd = -1;
static int signalFd = -1;
static boost::asio::io_service gIoSvc;
//A simple test program to test whether signalfd works with boost::asio or not.
static boost::asio::posix::stream_descriptor *gwMqFd = nullptr; //message queue on which the gateway listens for control requests.
static boost::asio::posix::stream_descriptor *inFd = nullptr; //message queue on which the gateway listens for control requests.
static void
handleMqRead(boost::system::error_code ec)
{
std::cerr<<"\nRecvd signal";
struct signalfd_siginfo fdsi;
memset(&fdsi, 0, sizeof(fdsi));
ssize_t s = ::read(signalFd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo)){
std::cerr<<"read() on signalfd returns inconsistent size.";
return;
}
gwMqFd->async_read_some(boost::asio::null_buffers(),
boost::bind(&handleMqRead,
boost::asio::placeholders::error));
return;
}
#define EVENT_SIZE (sizeof (struct inotify_event))
#define EVENT_BUF_LEN (1024*(EVENT_SIZE + 16))
static void
observeFilesystem(boost::system::error_code ec)
{
std::cerr<<"\nDirectory modified ...";
char buf[EVENT_BUF_LEN];
int length = ::read(inotifyFd, buf, sizeof(buf));
inFd->async_read_some(boost::asio::null_buffers(),
boost::bind(&observeFilesystem,
boost::asio::placeholders::error));
return;
}
int
main(int argc, char* argv[])
{
try{
inFd = new boost::asio::posix::stream_descriptor(gIoSvc);
gwMqFd = new boost::asio::posix::stream_descriptor(gIoSvc);
sigset_t signalMask;
sigemptyset(&signalMask);
sigaddset(&signalMask, SIGCHLD);
sigaddset(&signalMask, SIGTERM);
sigprocmask(SIG_BLOCK, &signalMask, nullptr);
signalFd = signalfd(-1, &signalMask, SFD_NONBLOCK | SFD_CLOEXEC);
assert(signalFd > 0);
gwMqFd->assign(signalFd);
gwMqFd->async_read_some(boost::asio::null_buffers(),
boost::bind(&handleMqRead,
boost::asio::placeholders::error));
inotifyFd = inotify_init();
assert(inotifyFd > 0);
inFd->assign(inotifyFd);
std::string fqpn = ".";
inotify_add_watch(inotifyFd, fqpn.c_str(), IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY);
inFd->async_read_some(boost::asio::null_buffers(),
boost::bind(&observeFilesystem,
boost::asio::placeholders::error));
gIoSvc.run();
}catch (std::exception& e){
std::cerr << "Exception: " << e.what() << std::endl;
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
//编译
//-------------
//g++-std=c++0x-g-I/usr/local/include-I/home/rk/Downloads/websocketpp/src asio.cc-L/home/rk/Downloads/websocketpp-L/usr/local/lib/-lwebsocketpp-lboost_线程-lboost_异常-lboost_日期_时间-lboost_regex-lboost_系统-o asio
静态int-inotifyFd=-1;
静态int信号fd=-1;
静态boost::asio::io_服务gIoSvc;
//一个简单的测试程序,用于测试signalfd是否与boost::asio一起工作。
静态boost::asio::posix::stream_描述符*gwMqFd=nullptr//网关侦听控制请求的消息队列。
静态boost::asio::posix::stream_描述符*inFd=nullptr//网关侦听控制请求的消息队列。
静态空隙
handleMqRead(boost::system::error_code ec)
{
标准:cerr 0);
inFd->assign(inotifyFd);
标准::字符串fqpn=“.”;
inotify|u add|u watch(inotiffd,fqpn.c|u str(),IN|CREATE | IN|DELETE | IN|DELETE | IN|MOVE | u SELF | IN| MODIFY);
inFd->async\u read\u some(boost::asio::null\u buffers(),
boost::绑定和观察文件系统,
boost::asio::占位符::错误);
gIoSvc.run();
}捕获(标准::异常&e){
我想说的是,而不是使用
int length = ::read(inotifyFd, buf, sizeof(buf));
inFd->async_read_some(boost::asio::null_buffers(),
boost::bind(&observeFilesystem,
boost::asio::placeholders::error))
最好完全利用aync\u阅读以下内容
inFd->async_read_some(
boost::asio::buffer(buf, EVENT_BUF_LEN),
boost::bind(&observeFilesystem,
boost::asio::placeholders::error));
谢谢你的回答,我重写了fd变量。但这不是问题。我缩小了这个问题的范围。你能帮我解释一下吗。希望看到你的答案-1。没有给出解释。它依赖于..一个替代但更高级别的库。为+1添加一些解释:)你能结合boost::asio吗代码>和inotify
?