【问题标题】:Multithreaded file search多线程文件搜索
【发布时间】:2020-01-05 14:50:54
【问题描述】:

我想知道我应该如何解决以下问题。我的 c 程序将接收 3 个参数 - 要调用的路径、术语和线程数

我应该在 path 的任何子目录中探索名称中包含 term 的文件。如果我的程序是异步的,那将是一项相当容易的工作。

我正在为我的线程使用共享队列,并使用条件变量进行同步。

我的逻辑如下 -

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..)
}

这是一个伪代码而不是真正的代码,但我更担心我的逻辑而不是我的实现。 我的问题是,我如何向我的线程发出空队列信号以结束其功能的信号,并且在队列包含某些路径之前,这不仅仅是暂时的。

我很想听听你的意见!

【问题讨论】:

  • 你的入口是错误的。互斥体应该在调用pthread_cond_wait 之前被锁定(事实上,在进入循环本身之前),此外,在调用返回时它已经被锁定,除非出现错误。冒着听起来自私的风险,read this.
  • 未显示的代码会初始化 condmute,不是吗?
  • 你不应该在锁定互斥锁的情况下递归iterate_dir(),对吗?它将限制并发性。

标签: c multithreading pthreads


【解决方案1】:

我更担心我的逻辑而不是我的实现。我的问题 是,我如何向我的线程发出空队列信号以结束它们的信号 函数,并且在队列包含之前它不仅仅是暂时的 一些路径。

我认为您在问如何处理队列为空不构成适当的线程终止条件的事实,因为新目录可能被仍然处于活动状态的任何线程排队。答案很简单:不要使用队列空作为(唯一的)终止条件。相反,维护另一个共享变量来跟踪当前处理目录的线程数 - 也在互斥锁的保护下 - 并使循环终止条件为队列为空并且没有线程正在处理目录.

还要注意,你必须

  • 注意确保所有对共享状态的访问都受到互斥锁的保护。在循环条件中包括队列空测试。
  • 注意尽可能限制互斥体的范围,以允许最大的并发量。
  • 准备好处理虚假唤醒。

逻辑可能看起来更像这样:

// ...

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..)
}

【讨论】:

  • 出色的答案,我会尝试实现这个逻辑!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 2013-05-28
  • 1970-01-01
相关资源
最近更新 更多