2

解决了

我将 bfs::directory_iterator 队列更改为 std::string 队列,出人意料地解决了这个问题。


嗨,我有一种直觉,我做错了事。

我已经实现(或试图)线程池模式。

N 个线程从队列中读取,但我遇到了一些麻烦。这是我得到的:

//inside a while loop
bool isEmpty;
bfs::directory_iterator elem;

{   
    boost::mutex::scoped_lock lock(this->queue_mutex);
    isEmpty = this->input_queue.isEmpty();

    if (!isEmpty){

        elem= *(this->input_queue.pop());
    }   
    else{
        continue;
    }   
}

scoped_lock 是否仍然可以在 if 的主体内工作?我开始相信它不会(在运行了许多测试之后)。如果没有,是否有任何范围的方法来做到这一点(即不是显式锁定解锁方式)

提前致谢。

更新

将元素添加到队列的代码如下所示

  //launches the above code, passing a reference to mutex and queue.
   Threads threads(queue,queue_mutex);

    for (bfs::directory_iterator dir_it:every file in directory){
      boost::mutex::scoped_lock lock(queue_mutex);
      
      queue.push(dir_it);
    
    
    }

我放置了一个 cout 来控制弹出的文件名,如果我推送 2 个文件(file1)和(file2),并使用 2 个线程,我会得到两个“file2”。

  class Threads{
    
   boost::thread::thread_group group; 
    Thread (N){
          
    //also asigns a reference to a queue and a mutex.
     for(i 1..N){ 
       //loop is posted above.
       group.add(new boost::thread(boost::bind(&loop,this)));
     }
    }
 };
    
4

3 回答 3

1

发布的代码看起来很好 - 如果您看到问题,可能还有其他一些地方应该锁定而不是锁定(例如向队列添加某些内容的代码)。

于 2009-09-23T19:53:56.447 回答
0

不,如果将锁移到 内部,则该锁将不起作用if,因为在检查空虚时会出现竞争条件。最后一个元素可能在检查和锁定之间被删除。

于 2009-09-23T19:12:56.493 回答
0

我会将锁添加到队列中......管理队列外部的锁很棘手,往往会混淆代码,但由于未锁定的数据结构被暴露,因此也很脆弱。

似乎获得队列实用程序的模式是 try_pop 和 try_push 方法。.NET 的并行扩展正在将此模式与 System.Collections.Concurrent.ConcurrentQueue 一起使用。

这可以通过无锁队列或简单地将队列和锁嵌入到具有适当接口的容器中来完成。Anthony Williams 有一篇关于如何在此处使用 std::queue 执行此操作的好帖子。

您的代码可能如下所示:

//inside a while loop
bfs::directory_iterator elem;

while (this->input_queue.pop(*elem))
{
  ... // do something
}
于 2009-09-25T07:07:00.940 回答