Многопоточный поиск файлов - PullRequest
0 голосов
/ 05 января 2020

Мне было интересно, как мне подойти к следующей проблеме. Моя c программа получит 3 аргумента - путь, срок и количество потоков для вызова.

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

Я использую общую очередь для своих потоков, с lock и условной переменной для синхронизации.

My logi c выглядит следующим образом -

int main(int argc, char *argv)
{
 ...
Queue *queue = init_queue();
enqueue(queue, root_path);    

for (int i = 0; i<n_threads; ++i)
    pthread_create(..., thread_handle, ...);
 ...
}

void thread_handle()
{

    while (!queue_empty)
    {
          while(!condition_variable)
              pthread_cond_wait(&cond);
          pthread_mutex_lock(&lock);
          QNode *node = dequeue(queue);  
          iterate_dir(node->path);
          pthread_mutex_unlock(&lock);
          thread_cond_signal(condition_variable);
    }
}

void iterate_dir(...)
{
    // Directory search logic (with enqueue..)
}

Это скорее псевдо-код, чем реальный код, но меня больше беспокоит моя логика c, чем моя реализация. У меня вопрос: как я могу сигнализировать своим потокам, что пустые сигналы очереди заканчивают свою функцию, и это не просто временно, пока в очереди не будет указан какой-либо путь.

Я хотел бы услышать ваше мнение!

1 Ответ

1 голос
/ 06 января 2020

Меня больше беспокоит моя логика c, чем моя реализация. Мой вопрос: как я могу сигнализировать своим потокам, что пустые сигналы очереди заканчивают свою функцию, и это не просто временно, пока в очереди не будет указан какой-либо путь.

Я думаю, вы спрашиваете, как поступить с тем фактом, что очередь пуста, не является подходящим условием завершения потока, поскольку новые каталоги могут ставиться в очередь любыми потоками, которые все еще активны Ответ прост: не используйте пустоту очереди в качестве (единственного) условия завершения. Вместо этого следует поддерживать другую разделяемую переменную, которая отслеживает количество потоков, которые в настоящее время обрабатывают каталоги - также находящиеся под защитой мьютекса, - и сделать условие завершения l oop, состоящее в том, что очередь пуста и нет потоков Обработка каталогов.

Обратите также внимание, что вы должны

  • позаботиться о том, чтобы все доступы к общему состоянию были защищены мьютексом. Включая тест очереди-пустоты в условие l oop.
  • позаботьтесь о том, чтобы максимально ограничить область действия мьютекса, чтобы обеспечить наибольшее количество параллелизма.
  • будьте готовы справиться с ложными пробуждениями.

Лог c может выглядеть так:

// ...

int num_active_threads = 0;

void *thread_handle(void *arg) {
    pthread_mutex_lock(&lock);
    while (true) {
        while (queue_empty && num_active_threads > 0) {
                pthread_cond_wait(&cond);
        }
        if (queue_empty) break; // it must (also) be that num_active_threads == 0, so all done
        QNode *node = dequeue(queue);  
        num_active_threads++;
        pthread_mutex_unlock(&lock);

        iterate_dir(node->path);

        pthread_mutex_lock(&lock);
        num_active_threads--;
        pthread_cond_broadcast(condition_variable);
    }
    pthread_mutex_unlock(&lock);
}

void iterate_dir(...)
{
    // Directory search logic (with MUTEX-PROTECTED enqueue..)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...