c - 多线程文件搜索
问题描述
我想知道我应该如何解决以下问题。我的 c 程序将接收 3 个参数 -路径、术语和要调用的线程数。
我应该在path的任何子目录中探索名称中包含该术语的文件。如果我的程序是异步的,那将是一项相当容易的工作。
我正在为我的线程使用共享队列,并使用锁和条件变量进行同步。
我的逻辑如下 -
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..)
}
这是一个伪代码而不是真正的代码,但我更担心我的逻辑而不是我的实现。我的问题是,我如何向我的线程发出空队列信号以结束其功能的信号,并且在队列包含某些路径之前,这不仅仅是暂时的。
我很想听听你的意见!
解决方案
我更担心我的逻辑而不是我的实现。我的问题是,我如何向我的线程发出空队列信号以结束其功能的信号,并且在队列包含某些路径之前,这不仅仅是暂时的。
我认为您在问如何处理队列为空不构成适当的线程终止条件的事实,因为新目录可能被仍然处于活动状态的任何线程排队。答案很简单:不要使用队列空作为(唯一的)终止条件。相反,维护另一个共享变量来跟踪当前处理目录的线程数——也在互斥锁的保护下——并使循环终止条件为队列为空且没有线程正在处理目录。
另请注意,您必须
- 注意确保对共享状态的所有访问都受到互斥锁的保护。在循环条件中包括队列空测试。
- 注意尽可能限制互斥体的范围,以允许最大的并发量。
- 准备好处理虚假唤醒。
逻辑可能看起来更像这样:
// ...
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..)
}
推荐阅读
- java - 无法在 Windows 10 上安装 Java 6
- java - Gradle 6.8.1 不使用 Junit 执行测试
- substrate - 安装基板验证器集时出错
- kotlin - 预初始化列表/集合/等的大小
- javascript - Gatsby:“警告有多个模块的名称只是大小写不同。这可能导致意外行为......”
- sql - TSQL Cross Apply 确定要查询的数据库
- mongoose - 代理背后的猫鼬。如何通过代理连接到 mongoDB
- python - 为什么我不能用 fernet [Python] 解密数据库值?
- sharepoint - 如何重置 SharePoint 内容数据库中的缓存?
- php - 在 HTML 表中显示 MySQL 数据库表