потокобезопасность — реализация ограниченной очереди блокировки с использованием переполнения стека

Я не очень знаком с очередью блокировки с безопасностью потока, поэтому я просто погуглил и нашел следующие ссылки:

  1. C ++ pthread блокировка очереди тупик (я думаю)

  2. http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

Поэтому я просто скопировал и создал свою очередь ограниченных блокировок, используя C ++. Есть ли проблемы с моей реализацией?

// Assume all includes are there
struct BoundedBlockingQueueTerminateException
: virtual std::exception,
virtual boost::exception
{

};

template<typename T>
class BoundedBlockingQueue
{
private:
std::queue<T>                        q;
boost::mutex                         mtx;
boost::mutex::condition_variable_any cond1; // q.empty() condition
boost::mutex::condition_variable_any cond2; // q.size() == size condition
int                                  nblocked1;
int                                  nblocked2;
bool                                 stopped;
int                                  size;

public:
BoundedBlockingQueue(int size)
: size(size), nblocked1(0), nblocked2(0), stopped(false)
{
if (size < 1)
{
// BOOST_THROW_EXCEPTION
}
}

~BoundedBlockingQueue()
{
Stop(true);
}

bool Empty()
{
boost::mutex::scoped_lock lock(mtx);
return q.empty();
}

std::size_t Size()
{
boost::mutex::scoped_lock lock(mtx);
return q.size();
}

bool TryPush(const T& item)
{
boost::mutex::scoped_lock lock(mtx);
if (q.size() == size)
return false;

q.push(item);
lock.unlock();
cond1.notify_one();
return true;
}

void WaitPush(const T& item)
{
boost::mutex::scoped_lock lock(mtx);

++nblocked2;
while (!stopped && q.size() == size)
cond2.wait(lock);
--nblocked2;

if (stopped)
{
cond2.notify_all();
BOOST_THROW_EXCEPTION(BoundedBlockingQueueTerminateException());
}

q.push(item);
lock.unlock(mtx);
cond1.notify_one();
}

bool TryPop(T& popped)
{
boost::mutex::scoped_lock lock(mtx);
if (q.empty())
return false;

popped = q.front();
q.pop();
lock.unlock(mtx);
cond2.notify_one();
return true;
}

void WaitPop(T& popped)
{
boost::mutex::scoped_lock lock(mtx);

++nblocked1;
while (!stopped && q.empty())
cond1.wait(lock);
--nblocked1;

if (stopped)
{
cond1.notify_all();
BOOST_THROW_EXCEPTION(BoundedBlockingQueueTerminateException());
}

popped = q.front();
q.pop();
cond2.notify_one();
}

void Stop(bool wait)
{
boost::mutex::scoped_lock lock(mtx);
stopped = true;
cond1.notify_all();
cond2.notify_all();

if (wait)
{
while (nblocked1)
cond1.wait(lock);
while (nblcoked2)
cond2.wait(lock);
}
}
};

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …