如何避免命名管道中的多个作者?
Posted
技术标签:
【中文标题】如何避免命名管道中的多个作者?【英文标题】:How to avoid multiple writers in a named pipe? 【发布时间】:2010-12-29 14:32:54 【问题描述】:我正在编写一个带有多个读取器和多个写入器的命名管道的程序。这个想法是使用该命名管道来创建读取器/写入器对。那就是:
A 读取管道 B 在管道中写入 (反之亦然) A-B 对已创建!为了保证只有一个进程在读,一个在写,我用了2个锁和flock。就这样。
阅读器代码:
echo "[JOB $2, Part $REMAINING] Taking next machine..."
VMTAKEN=$((
flock -x 200;
cat $VMPIPE;
)200>$JOINQUEUELOCK)
echo "[JOB $2, Part $REMAINING] Machine $VMTAKEN taken..."
编写者代码:
((
flock -x 200;
echo "[MACHINE $MACHINEID] I am inside the critical section"
echo "$MACHINEID" > $VMPIPE;
echo "[MACHINE $MACHINEID] Going outside the critical section"
)200>$VMQUEUELOCK)
echo "[MACHINE $MACHINEID] Got new Job"
我有时会遇到以下问题:
[MACHINE 3] I am inside the critical section
[JOB 1, Part 249] Taking next machine...
[MACHINE 3] Going outside the critical section
[MACHINE 1] I am inside the critical section
[MACHINE 1] Going outside the critical section
[MACHINE 1]: Got new Job
[MACHINE 3]: Got new Job
[JOB 1, Part 249] Machine 3
1 taken...
如您所见,另一位作家在读者读完之前就写了。我能做些什么来摆脱这个问题?我应该使用 ACK 管道还是什么?
提前谢谢你
【问题讨论】:
flock
命令的语义是什么?它锁定了哪个文件?谁写的?你确定它做了它应该做的事吗? (我只能找到 flock()
函数调用的手册页,而不是包装它的命令。)
看来问题不在于羊群,而在于在命名管道中写入。从输出中可以看到,两台机器不同时处于临界区。
【参考方案1】:
这将是信号量的典型用途:
创建 2 个信号量 - 一个用于读取处理,另一个用于写入处理。将每个信号量设置为值 1
在阅读器的信号量上读取进程 sem_wait(2),直到信号量 > 0,如果得到它,则将其降低到零。
编写过程将使用为它们准备的信号量做同样的事情
控制进程(也可能最初设置信号量)可以检查两个信号量是否为零并分配对
读取器/写入器释放信号量(再次将它们增加 1),以便下一个读取器或写入器获得信号量。
为了在读写器之间传递信息,可以使用共享内存...
【讨论】:
以上是关于如何避免命名管道中的多个作者?的主要内容,如果未能解决你的问题,请参考以下文章
如何避免回显关闭 FIFO 命名管道? - Unix FIFO 的有趣行为
如何使用 Unix(或 Windows)中的(最好是未命名的)管道将一个进程的标准输出发送到多个进程?