2016-10-27 2 views
0

Я пытаюсь использовать Inotify в C++ внутри нити но выбор блокирует, поэтому я никогда не может выйти за пределы нити, когда мое приложение выходитнеблокирующем выбрать для Inotify

как я создаю Inotify часы

fd=inotify_init1(IN_NONBLOCK); 
// checking for error 
if (fd < 0) 
    log->Print("Could not init files listener"); 
else 
{ 
    // use select watch list for non-blocking inotify read 
    FD_ZERO(&watch_set); 
    FD_SET(fd, &watch_set); 

    int flags = fcntl(fd, F_GETFL, 0); 
    fcntl(fd, F_SETFL, flags | O_NONBLOCK); 

    // watch directory for any activity and report it back to me 
    int wd=inotify_add_watch(fd,folder.c_str(),IN_ALL_EVENTS); 

    // add wd and directory name to Watch map 
    watch.insert(-1, folder, wd); 

    // start listening thread 
    run(FilesListener::threadBootstrap); 
} 

здесь функция вызывается в моей петле нити

void FilesListener::refresh() 
{ 
    char buffer[1024]; 

    // select waits until inotify has 1 or more events. 
    // select needs the highest fd (+1) as the first parameter. 
    select(fd+1, &watch_set, NULL, NULL, NULL); 

    // Read event(s) from non-blocking inotify fd (non-blocking specified in inotify_init1 above). 
    int length = read(fd, buffer, EVENT_BUF_LEN); 
    if (length < 0) 
     log->Print("Could not read inotify file descriptor"); 
    else 
    { 
    .... 
+0

«Никогда не может выйти за пределы« Что это значит? 'select' * * разработан * для блокировки, пока вы не сможете прочитать или написать. Его также можно использовать, чтобы проверить, есть ли у вас что-то, что нужно читать, без блокировки, но вы не проверяете, что 'select' возвращает, так что это явно не то, что вы хотите. Вы можете просто удалить вызов на 'select' вообще. –

+0

Что вы пытаетесь достичь с помощью выбора? –

+0

Я удалил select и отлично работает, все еще задаюсь вопросом, зачем использовать «select», если не написать программу, которая будет убита CTRL + Z – user7082181

ответ

0
void FilesListener::refresh() 
{ 
    char buffer[1024]; 

    int length = read(fd, buffer, EVENT_BUF_LEN); 
    if (length >=0) 
    { 
    .... 
+0

. Чтобы добавить дополнительную информацию, используйте ссылку для редактирования по вашему вопросу. Кнопка «Ответ на сообщение» должна использоваться только для полных ответов на вопрос. - [Из обзора] (/ review/low-quality-posts/14129596) – tofro

+0

ну, я не получил лучшего ответа или информации, поэтому помогите себе – user7082181

0

Check https://github.com/paulorb/FileMonitor имеет удобный интерфейс для достижения того, чего вы хотите. Это порт API окон для Linux, использующий inotify.

Пример:

#include "FileMonitor.hpp" 

int main(void) 
{ 

    int m_EventID = FindFirstChangeNotification("/media/sf_P_DRIVE/FileMonitor/", 0, FILE_NOTIFY_CHANGE_FILE_NAME); 

    int ret = WaitForSingleObject(m_EventID, 10000); 
    printf("\nFinish %d", ret); 
    fflush(stdout); 

    FindNextChangeNotification(m_EventID); 

    int ret2 = WaitForSingleObject(m_EventID, 10000); 
    printf("\nFinish %d", ret2); 

    FindCloseChangeNotification(1); 
    printf("\nChangeNotification done"); 
    fflush(stdout); 

    return 0; 
} 

Если вы предпочитаете сделать это самостоятельно попробовать использовать функцию опроса, вы можете использовать его внутри нити.

 struct pollfd pfd = { th_params->fd, POLLIN, 0 }; 
     int ret = poll(&pfd, 1, 50); // timeout of 50ms 
     if (ret < 0) { 
      printf("\failed poll"); 


     } 
     else if (ret == 0) { 
      // Timeout with no events, move on. 
      printf("\nTimeout poll"); 

     } 
     else { 

      i = 0; 
      int lenght = read(th_params->fd, buffer, 1024); 
     } 
Смежные вопросы