2008-12-05 2 views
1

Я хочу отслеживать в режиме реального времени изменения нескольких каталогов в одном потоке, поэтому я решил использовать метод ReadDirectoryChangesW() асинхронно с GetQueuedCompletionStatus. Вот не мой код:Заблокировать тупик при использовании ReadDirectoryChangesW асинхронно

static DWORD WINAPI Routine(LPVOID lParam) 
{ 
    FileSystemWatcher* obj = (FileSystemWatcher*)lParam; 

    obj->hDir[0] = CreateFile(
     obj->WatchedDir[0].c_str(), 
     GENERIC_READ|GENERIC_WRITE, 
     FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 
     NULL, 
     OPEN_EXISTING, 
     FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, 
     NULL 
    ); 

    obj->hDir[1] = CreateFile(
    obj->WatchedDir[1].c_str(), 
    GENERIC_READ|GENERIC_WRITE, 
    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 
    NULL, 
    OPEN_EXISTING, 
    FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, 
    NULL 
    ); 

    if(INVALID_HANDLE_VALUE == obj->hDir[0] || INVALID_HANDLE_VALUE == obj->hDir  [1]) 
{ 
    return false; 
} 

obj->IOCPHandle[0] = CreateIoCompletionPort(obj->hDir[0], NULL, 0, 1); 
obj->IOCPHandle[1] = CreateIoCompletionPort(obj->hDir[1], NULL, 0, 1); 

if (obj->IOCPHandle[0] == INVALID_HANDLE_VALUE || obj->IOCPHandle[1] == INVALID_HANDLE_VALUE) 
{ 
    return false; 
} 

    char buf[ 2*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH) ]; 
    FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)buf; 
    DWORD BytesReturned; 
    LPOVERLAPPED overLap = NULL; 

    m_pFileNotifyInfo = pNotify; 
    dirEvents[0] = CreateEvent(NULL, TRUE, FALSE, NULL); 
    dirEvents[1] = CreateEvent(NULL, TRUE, FALSE, NULL);*/ 

    while(true) 
    { 

    BOOL success = ReadDirectoryChangesW(obj->hDir[0], 
    pNotify, 
    sizeof(buf), 
    true, 
    FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, 
    &BytesReturned, 
    overLap, 
    NULL); 
    BOOL success1 = ReadDirectoryChangesW(obj->hDir[1], 
    pNotify, 
    sizeof(buf), 
    true, 
    FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, 
    &BytesReturned, 
    overLap,  
       NULL); 

    LPOVERLAPPED theOverLap; 
    PULONG_PTR lpCompKey = NULL; 
    if (GetQueuedCompletionStatus(obj->IOCPHandle[0], &BytesReturned, lpCompKey, &overLap, 100)) 
    { 
    cout<<"First Dir Changed"<<endl; 
    } 

    if (GetQueuedCompletionStatus(obj->IOCPHandle[1], &BytesReturned, lpCompKey, &overLap, 100)) 
    { 
    cout<<"Second Dir Changed"<<endl; 
    } 

    cout<<"Nothing happened yet"<<endl; 

     } 

    return 0; 
} 

Вот когда я запускаю мой код, мои нити блоки без причины, независимо от того, какое значение я устанавливаю до последнего параметра GetQueuedCompletionStatus функции(). Я не знаю, почему я столкнулся с этой проблемой. Может ли кто-нибудь объяснить мою причину? Большое спасибо!

ответ

1
  1. Вы должны указать действительную структуру OVERLAPPED для работы асинхронного ввода-вывода. Вы используете NULL (LPOVERLAPPED overLap = NULL;).

  2. Операции параллельного ввода-вывода должны использовать отдельные структуры OVERLAPPED, а не только одну.

  3. Вы уверены, что вам нужен IOCP? Я бы просто заполнил hEvent в структурах OVERLAPPED и сделал WaitForMultipleObjects на этих мероприятиях.

Смежные вопросы