私のアプリはメインプロセスと2つのスレッドで構成されており、すべて同時に実行され、3つのFIFOキューを使用しています。
fifo-qは、Qmain、Q1、およびQ2です。内部的には、キューはそれぞれ、アイテムがキューに入れられるとインクリメントされ、アイテムがキューから取得されるとデクリメントされるカウンターを使用します。
処理には
、Q1とQ2から取得してQmainに配置されるQMaster、
Q2に配置されるMonitor、
およびQmainから取得してQ1に配置されるメインプロセスの2つのスレッドが含まれます。
QMaster-threadループは、Q1とQ2のカウントを連続してチェックし、qにアイテムがある場合は、それらを取得してQmainに配置します。
Monitor-threadループは、外部ソースからデータを取得し、パッケージ化してQ2に配置します。
アプリのメインプロセスは、Qmainのカウントをチェックするループも実行し、アイテムがある場合は、ループの各反復でQmainからアイテムを取得し、さらに処理します。この処理中に、アイテムをQ1に入れて、後で処理することがあります(Qmainから順番に取得される場合)。
問題:
上記のようにすべてを実装しましたが、ランダムに(短い)時間動作してからハングします。私は、fifo-qのカウントのインクリメント/デクリメントで発生するクラッシュの原因を特定することができました(それらのいずれかで発生する可能性があります)。
私が試したこと
:QMAIN_LOCK、Q1_LOCK、Q2_LOCKの3つのミューテックスを使用します。これらは、関連するfifo-qでget/put操作が実行されるたびにロックします。結果:アプリが動作せず、ハングするだけです。
メインプロセスは常に実行を継続する必要があり、「読み取り」でブロックされてはなりません(名前付きパイプが失敗、ソケットペアが失敗)。
何かアドバイス?
ミューテックスを適切に実装していないと思いますが、どのようにすればよいですか?
(上記の設計の改善に関するコメントも歓迎します)
[編集]以下はプロセスと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() {...}
};