我的应用程序由主进程和两个线程组成,所有线程都同时运行并使用三个 fifo 队列:
fifo-q 是 Qmain、Q1 和 Q2。在内部,每个队列都使用一个计数器,该计数器在将项目放入队列时递增,并在从队列中“获取”项目时递减。
处理涉及两个线程,
QMaster,从Q1和Q2获取,放入Qmain,
Monitor,放入Q2,
主进程,从Qmain获取,放入Q1。
QMaster-thread 循环连续检查 Q1 和 Q2 的计数,如果有任何项目在 q 中,它会获取它们并将它们放入 Qmain。
Monitor-thread循环从外部获取数据,打包后放入Q2。
应用程序的主进程还运行一个循环检查 Qmain 的计数,如果有任何项目,则在循环的每次迭代中从 Qmain 获取一个项目并进一步处理它。在此处理期间,它偶尔会将项目放入 Q1 以供稍后处理(当它依次从 Qmain 获取时)。
问题:
我已经按照上述方式实现了所有功能,它在随机(短)时间内工作,然后挂起。我已经设法确定崩溃的来源发生在 fifo-q 计数的递增/递减中(它可能发生在其中任何一个中)。
我尝试过:
使用三个互斥锁:QMAIN_LOCK、Q1_LOCK 和 Q2_LOCK,只要在相关的 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() {...}
};