Мое приложение состоит из основного процесса и двух потоков, все из которых работают одновременно и используют три очереди fifo:
Five-q - это Qmain, Q1 и Q2.Внутри каждой очереди используется счетчик, который увеличивается, когда элемент помещается в очередь, и уменьшается, когда элемент «извлекается» из очереди.
В обработке участвуют два потока,QMaster, который получают из Q1 и Q2 и помещают в Qmain,Монитор, который положил в Q2,и основной процесс, который получает из Qmain и помещает в Q1.
Цикл QMaster-thread последовательно проверяет счетчики Q1 и Q2 и, если какие-либо элементы находятся в q, он получает их и помещает их в Qmain.
Цикл Monitor-thread получает данные из внешних источников, упаковывает их и помещает в Q2.
Основной процесс приложения также запускает цикл, проверяющий счетчик Qmain, иесли есть какие-либо элементы, получайте элемент из Qmain на каждой итерации цикла и обрабатывайте его дальше.Во время этой обработки он иногда помещает элемент в Q1 для последующей обработки (когда он по очереди получает от Qmain).
Проблема:Я реализовал все как описано выше, и он работает в течение случайного (короткого) времени, а затем зависает.Мне удалось определить причину сбоя в увеличении / уменьшении счетчика fifo-q (это может произойти в любом из них).
Что я пробовал:Используя три мьютекса: QMAIN_LOCK, Q1_LOCK и Q2_LOCK, которые я блокирую всякий раз, когда любая операция get / put выполняется на соответствующем fifo-q.Результат: приложение не запускается, просто зависает.
Основной процесс должен постоянно работать, не должен блокироваться при чтении (сбой именованных каналов, сбой сокета пары).
Есть совет?Я думаю, что неправильно внедряю мьютекс, как это должно быть сделано?(Любые комментарии по улучшению вышеуказанного дизайна также приветствуются)
[править] ниже приведены процессы и шаблон fifo-q:Где и как в этом месте разместить мьютекс, чтобы избежать проблем, описанных выше?
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() {...}
};