Мое приложение состоит из основного процесса и двух потоков, все работают одновременно и используют три очереди fifo:
Фигу-q - Qmain, Q1 и Q2. Внутри каждой очереди каждый использует счетчик, который увеличивается, когда элемент помещается в очередь, и уменьшается, когда элемент "получает" из очереди.
Обработка включает в себя два потока,
QMaster, которые получают от Q1 и Q2 и помещаются в Qmain,
Монитор, который помещается в Q2,
и основной процесс, который поступает из Qmain и помещается в Q1.
Цикл цикла QMaster последовательно проверяет количество Q1 и Q2, и если какие-либо элементы находятся в q, они получают их и помещают в Qmain.
Цикл Monitor-thread получает данные из внешних источников, упаковывает их и помещает в Q2.
В главном процессе приложения также выполняется цикл, проверяющий количество Qmain, и если какие-либо элементы получают элемент от Qmain на каждой итерации цикла и обрабатывать его дальше. Во время этой обработки это время от времени помещает элемент в Q1, который будет обработан позже (когда он будет получен от Qmain по очереди).
Проблема:
Я реализовал все, как описано выше, и работает в случайном (коротком) времени, а затем зависает.
Мне удалось определить источник сбоя, чтобы произойти в приращении/уменьшении
счетчик fifo-q (это может произойти в любом из них).
Что я пробовал:
Использование трех мьютексов: QMAIN_LOCK, Q1_LOCK и Q2_LOCK, которые я блокирую при любой операции get/put
делается на соответствующем fifo-q. Результат: приложение не работает, просто зависает.
Основной процесс должен продолжаться все время, не должен быть заблокирован на "read" (сбой имени named-pipe, failer socketpair).
Любые советы?
Я думаю, что я не правильно использую мьютекс, как это сделать?
(Любые комментарии по улучшению вышеуказанного дизайна также приветствуются)
[править] ниже - процессы и fifo-q-template:
Где и как в этом случае я должен помещать мьютексы, чтобы избежать описанных выше проблем?
main-process:
...
start thread QMaster
start thread Monitor
...
while (!quit)
{
...
if (Qmain.count() > 0)
{
X = Qmain.get();
process(X)
delete X;
}
...
//at some random time:
Q2.put(Y);
...
}
Monitor:
{
while (1)
{
//obtain & package data
Q2.put(data)
}
}
QMaster:
{
while(1)
{
if (Q1.count() > 0)
Qmain.put(Q1.get());
if (Q2.count() > 0)
Qmain.put(Q2.get());
}
}
fifo_q:
template < class X* > class fifo_q
{
struct item
{
X* data;
item *next;
item() { data=NULL; next=NULL; }
}
item *head, *tail;
int count;
public:
fifo_q() { head=tail=NULL; count=0; }
~fifo_q() { clear(); /*deletes all items*/ }
void put(X x) { item i=new item(); (... adds to tail...); count++; }
X* get() { X *d = h.data; (...deletes head ...); count--; return d; }
clear() {...}
};