2013-05-06 3 views
2

내가 소스 코드를 기반으로 모니터링 파일 프로그램을 쓰고 있어요 실패비동기 읽기는

생성자 :

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_))); 
} 

을 inotify를 설명 http://linux.die.net/man/7/inotify

내 코드는 다음과 같습니다 비동기 읽기 :

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)); 
} 

핸들러 :

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); 

} 

오류가 처음 handle_monitor에서의 첫 번째 변화를 여러 번 (예 : MODIFY, ACCESS, OPEN 여러 이벤트를 ...) 호출이다 감시하는 파일 그런 다음 async_read_some 메서드가 다시 호출되었지만 더 이상 신호가 없습니다 (handle_monitor가 더 이상 호출되지 않음)

그러나 설명을 재설정하고 모니터링 할 파일을 다시 읽으려고하면 ==> 작동했습니다. handle_monitor는 모니터링되는 파일의 새로운 변경 사항에 대해 호출됩니다.

코드 수정 :

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 

} 

너희들은 내가이 문제를 설명 할 수 있을까요 ???? 나는

답변

2

이 당신은 fd 대신 fd_notify_init1()에서 반환 된 값과 stream_descriptor을 만들어야합니다 나를

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_))); 
} 

에 의심스러운 ..... 당신의 대답을 죽어 가고 있어요. fd_은 클래스 멤버이며 초기화되지 않았거나 0으로 초기화되었을 가능성이 높습니다.

+0

덕분에 다음과 같이 aync_read_some을 활용하는 더 나은 것 대신

int length = ::read(inotifyFd, buf, sizeof(buf)); inFd->async_read_some(boost::asio::null_buffers(), boost::bind(&observeFilesystem, boost::asio::placeholders::error)) 

를 사용하는 말을, 나는 FD 변수를 다시 작성합니다. 그러나 그것은 문제가 아닙니다. 나는이 문제에서 내 문제의 범위를 좁힌 다. http://stackoverflow.com/questions/16397293/the-read-method-on-the-inotify-descriptor-does-not-return 설명해 주시겠습니까? 당신의 대답을 보길 바랍니다 – khanhhh89

-1
#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; 
} 
+0

-1. 설명이 없다. 그것은 https://github.com/zaphoyd/websocketpp에 의존합니다. 그러나 더 높은 수준의 라이브러리. +1에 대한 설명 추가 :) – matiu

1

나는 완전히 당신의 답변을

inFd->async_read_some(
boost::asio::buffer(buf, EVENT_BUF_LEN), 
boost::bind(&observeFilesystem, 
boost::asio::placeholders::error));