Increase scoped_lock. Will there be this castle?

solved

I changed the bfs :: directory_iterator Queue to std :: string and unexpectedly solved the problem.


Hi, I have a feeling that I am doing something wrong.

I have implemented (or tried) the thread pool pattern.

N threads read from the queue, but I'm having problems. This is what I got:

//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;
    }   
}

      

Will scoped_lock work inside the if body? I'm starting to believe it won't (after many tests). If not, is there any way to do this (I'm not an explicit way to block the lock)

Thanks in advance.

Update

The code that adds items to the queue looks like this:

  //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);


    }

      

I set up cout to control the filename popup, and if I hit 2 files (file1) and (file2) and use 2 streams, I get both "file2" files.

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

      

+2


source to share


3 answers


The selected code looks accurate - if you see problems, there may be some other place where the lock should be taken and not (for example, code that adds something to the queue).



+1


source


No, the lock won't work if it moves inside if

, because there will be a race condition to check against void. The last item can be removed between check and lock.



0


source


I'd add a lock to the queue ... managing locks external to the queue is tricky, tends to confuse code, but also quite fragile since the data structure is unlocked.

The pattern that seems to get the utility for queues is the try_pop and try_push method. .NET concurrent extensions leverage this pattern with System.Collections.Concurrent.ConcurrentQueue.

This is done either without blocking, or by simply embedding the queue and blocking into a container with appropriate interfaces. Anthony Williams has a good article on how to do this with std :: queue here .

your code might look like:

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

while (this->input_queue.pop(*elem))
{
  ... // do something
}

      

0


source







All Articles