Простой многопоточный код win32. Может ли это работать? - PullRequest
0 голосов
/ 07 октября 2019

Я хочу реализовать приложение, имеющее поток, который пересекает все файлы на диске, в то время как другой поток проверяет условие.

При достижении условия поток, пересекающий файлы, закрывается .

У меня есть РЕЗЬБА МОНИТОРА вот так

while(true){

    //--------CHECK CONDITION---------

    if(MEETS_CONDITION){
        //PostThreadMessage WM_QUIT to the SCANNING THREAD

        break;
    }
    Sleep(1000);
}

И у меня СКАНИРОВАНИЕ вот так

while(true){

//-------do scanning files------------

//PeekMessage and check if it's WM_QUIT
//if it is, then BREAK.

Sleep(10000);
}

Все два потока созданы MAIN THREAD .

Может ли этометод работы?

Любые предложения будут приветствоваться.

РЕДАКТИРОВАТЬ:

поток монитора сканирует файлыне связано с потоком сканирования. Фактически, в моей программе поток монитора открывает указанный раздел реестра и проверяет, существует ли файл, на который указывает этот ключ . А в потоке сканирования проходит по всему диску, чтобы собрать файлы, соответствующие чему-то другому . Таким образом, два потока идут отдельно, а буферизация / небуферизация файлов не разделяется на два потока.

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

Ответы [ 2 ]

2 голосов
/ 07 октября 2019

Фактически, делегирование проверки потоком монитора не сэкономит ваше время, как вы думаете, но оно будет работать еще хуже.

Действительно, проверка замедлит цикл сканирования, но делегирует медленную обработкуПоток монитора не решит проблему. Поток монитора не может проверять файлы, которые еще не проверены, и поскольку он медленнее, чем поток сканирования, даже если в процессе сканирования будет достигнут нужный файл, вы продолжите сканирование ненужных файлов до тех пор, пока (медленный) поток монитора не обнаружитнаконец-то добрался и до нужного файла. Таким образом, вы ничего не получите, даже хуже, вы сделаете несколько лишних сканирований.

Еще хуже (опять же), чтобы делегировать проверку потоку монитора, вам нужно будет буферизовать отсканированные файлы так,что поток монитора сможет извлечь их и выполнить проверку для каждого из них. Следовательно, вы добавите некоторые задачи буферизации / снятия буферизации (не говоря о механизмах мьютекса, которые понадобятся, чтобы избежать одновременного доступа к буферу и условию гонки).

Я думаю, что лучше удалить поток монитора исделать все в теме сканирования. Это может выглядеть следующим образом:

void scanning_thread(const std::string & filename)
{
    bool found(false);
    bool finished(false);
    std::string current;

    do
    {
        current = find_next();   // For the example, I assumed this function exists
        if(current == filename)  // filename found
            found = true;
        else if(current.empty()) // end of search
            finished = true;
    }
    while(!found && !finished);

    // Do something you want
}
1 голос
/ 07 октября 2019

Может ли этот метод работать?

Да, и вам не нужно делать это определенным образом для WinAPI, используя PostThreadMessage и PeekMessage.

Ниже приведен простой пример. Для большего контроля посмотрите на std::mutex и std::condition_variable.

#include <atomic>
#include <filesystem>
#include <iostream>
#include <string>
#include <thread>

using namespace std::filesystem;

// A thread safe varible to signal when it's time to stop scanning
std::atomic<bool> stop_scanning = false;

// a function returning true after a lot of iterations
bool check_condition() {
    static long x = 0;
    if(++x == 1000000000) return true;
    //...
    return false;
}

void monitor_thread() {
    while(true) {
        if(check_condition()) {
            stop_scanning = true;
            break;
        }
    }
}

void scanning_thread() {
    std::string top_dir = ".";
    while(true) { // continuously scan from a certain top directory and down
        for(auto& dir_entry : recursive_directory_iterator(top_dir)) {
            if(stop_scanning) return; // the monitor thread wants us to stop
            // ... work with "dir_entry"
        }
    }
}

int main() {
    auto monitor = std::thread(monitor_thread);
    auto scanner = std::thread(scanning_thread);
    monitor.join();
    scanner.join();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...