4

I like C# thread-safe BlockingCollection that allows me to "block" until new items are available, using Take and TryTake methods, for example block maximum for 1 second: orderActions.TryTake(out oa, 1000);

What would be c++ / boost analog of BlockingCollection?

Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • In Boost there's the opposite: lockfree thread-safe queue (http://www.boost.org/doc/libs/1_54_0/doc/html/lockfree.html) – Igor R. Sep 27 '13 at 06:12

1 Answers1

5

You could use boost::lockfree library to achieve desired behavior. In that case you can implement Take and TryTake on top of pop method.

Or you can use this answer to protect std::deque with std::mutex and std::condition_variable (answer written in terms of C++11 but you could use boost::thread to access thread related stuff from older compilers).

UPDATE

Actually I don't recommend first way cause it kills whole idea of lock-free container :) So, for the second case TryTake (tryPop) can be implemented with following code (just example)

template<typename PeriodT>
bool tryPop (T & v, PeriodT dur) {
    std::unique_lock<std::mutex> lock(this->d_mutex);
    if (!this->d_condition.wait_for(lock, dur, [=]{ return !this->d_queue.empty(); })) {
        return false;
    }
    v = std::move (this->d_queue.back());
    this->d_queue.pop_back();
    return true;
}    

PeriodT can be std::chrono::milliseconds, for example. Quick sample:

queue<int> p;
int v;
p.tryPop (v, std::chrono::milliseconds(1));
Community
  • 1
  • 1
Eugene Mamin
  • 749
  • 4
  • 8
  • I don't know how to implement Take and TryTake exactly. likely i should use `wait handle` but i was thinking to find something ready to use, cause it's too hard to implement for me :) – Oleg Vazhnev Sep 27 '13 at 06:31
  • @javapowered: Threading unfortunately is hard. You really have to learn to build it from the primitives (and than you should use something already existing to avoid bugs, but you have to understand how it works). – Jan Hudec Sep 27 '13 at 06:47
  • do you know what is better to place in `queue`? should I allocate object, place pointer, dequeue, delete object? or I should place references? or I should place objects itself? – Oleg Vazhnev Sep 27 '13 at 08:31
  • It depends on your task. In general, I wouldn't recommend raw pointers or just references. Placing objects itself good for Moveable classes which provide fast and cheap transfers across calls. In other cases use std::unique_ptr and std::shared_ptr to achieve memory safety and consistency. – Eugene Mamin Sep 27 '13 at 08:39
  • what if I need no timeout, should I just use `p.tryPop(v, std::chrono::milliseconds(0)))` ? – Oleg Vazhnev Nov 18 '13 at 12:15
  • adding reference to review of this code http://codereview.stackexchange.com/questions/49820/thread-safe-queue also how many consumer and producers this implementation supports? – Oleg Vazhnev Aug 28 '14 at 12:27