Работа над ошибками (нужна помощь зала).



В комментариях мой уважаемый подписчик Роман Митин указал что я на лекции показал неправильный пример bounded MPMC queue -- на самом деле извлечение и вставка там шли с одного конца и таким образом это был скорее bounded MPMC stack. Для многопоточной среды разница не так велика -- задачи ставятся в "очередь" и разбираются консьюмерами и в общем по циклограмме работы сложно отличить что там было. Но я решил сделать настоящую очередь и заодно улучшить тесты.



И вот тут я обратил внимание что у меня было ещё несколько ошибок, пока в комментариях не замеченных.



(1) В случае multi-producer делать wake_and_done надо на всех продьюсеров один раз иначе бывает так что консьюмеры повыходили но не все продьюсеры ещё закончили.

(2) Саму функцию wait_and_pop надо делать с сигнатурой bool wait_and_pop(T &Data) чтобы понимать есть там что консьюмить или нет

(3) Внутри wait_and_pop условие должно выглядеть так:



CondCons.wait(Lk, [this] { return !empty() || done(); });

if (empty())

return false;



Даже если у нас сигнализирован done, задачи могут быть недоразобраны и поэтому критерий return false это только empty.



(4) Внутри push признак done вообще проверять не надо т.к. это признак отработки всех продьюсеров. Там играет роль только full.

(5) В интерфейсе необходим метод is_empty_and_done() чтобы по нему консьюмеры понимали когда начинать выходить.



В общем это жесть. Пять ошибок в довольно простом коде и я не уверен что я ещё чего-то не пропустил.



Полу-финальные версии bounded stack и bounded queue с тестами на то что они не теряют задач я выложил сюда:



https://github.com/tilir/cpp-masters/blob/master/queues/classic_queue.cc

https://github.com/tilir/cpp-masters/blob/master/queues/classic_stack.cc



Нужна помощь зала в проверке не упустил ли я ещё чего-нибудь. Хочу в среду с этого начать лекцию и не хотелось бы облажаться ещё в чём-нибудь столь же тонком.



#questions