Почему многопоточность мешает моему наблюдателю файлов? - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь создать наблюдатель файлов, который просматривает несколько каталогов одновременно, и я нашел функцию, которая отслеживает один каталог, и она хорошо работает. Поэтому я попытался создать несколько потоков с одной и той же функцией и просто указать им разные пути к каталогам в качестве параметров. И он по-прежнему работает, но не идеально. Он предоставляет мне первое изменение в одном каталоге, но затем он застревает в этом каталоге, а в других каталогах вносимые мной изменения печатаются так, как если бы они были сделаны в первом каталоге. Я думаю, что нити перепутались, и я не знаю почему. Вот функция

void watch_directory(LPCSTR path, int i)
{

char buf[2048];
DWORD nRet;
BOOL result = TRUE;
char filename[MAX_PATH];
DirInfo[0].hDir = CreateFile(path, GENERIC_READ | FILE_LIST_DIRECTORY,
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
    NULL);

if (DirInfo[0].hDir == INVALID_HANDLE_VALUE)
{
    return; //cannot open folder
}

lstrcpy(DirInfo[0].lpszDirName, path);
OVERLAPPED PollingOverlap;

FILE_NOTIFY_INFORMATION* pNotify;
int offset;
PollingOverlap.OffsetHigh = 0;
PollingOverlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
while (result)
{
    result = ReadDirectoryChangesW(
        DirInfo[0].hDir,// handle to the directory to be watched
        &buf,// pointer to the buffer to receive the read results
        sizeof(buf),// length of lpBuffer
        TRUE,// flag for monitoring directory or directory tree
        FILE_NOTIFY_CHANGE_FILE_NAME |
        FILE_NOTIFY_CHANGE_DIR_NAME |
        FILE_NOTIFY_CHANGE_SIZE,
        &nRet,// number of bytes returned
        &PollingOverlap,// pointer to structure needed for overlapped I/O
        NULL);

    WaitForSingleObject(PollingOverlap.hEvent, INFINITE);
    offset = 0;
    int rename = 0;
    char oldName[260];
    char newName[260];
    do
    {
        pNotify = (FILE_NOTIFY_INFORMATION*)((char*)buf + offset);
        strcpy(filename, "");
        int filenamelen = WideCharToMultiByte(CP_ACP, 0, pNotify->FileName, pNotify->FileNameLength / 2, filename, sizeof(filename), NULL, NULL);
        filename[pNotify->FileNameLength / 2] = '\0';
        cout << pNotify->Action << i << filename << endl;
        offset += pNotify->NextEntryOffset;

    } while (pNotify->NextEntryOffset); //(offset != 0);
}

/*label:*/  CloseHandle(DirInfo[0].hDir);


}

А вот как я создаю потоки:

    vector <string> dirs;
vector <thread> threads;
dirs.push_back("F:\\Arhitecturi\\test0");
dirs.push_back("F:\\Arhitecturi\\test1");

for (int i = 0; i < dirs.size(); i++)
{

    threads.push_back(thread(watch_directory, dirs[i].c_str(), i));
}
for (int i = 0; i < threads.size(); i++)
{
    threads[i].join();

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...