如何避免命名管道中的多个作者?

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),以便下一个读取器或写入器获得信号量。

为了在读写器之间传递信息,可以使用共享内存...

【讨论】:

以上是关于如何避免命名管道中的多个作者?的主要内容,如果未能解决你的问题,请参考以下文章

SIGPIPE 如何影响命名管道中的作者?

如何避免回显关闭 FIFO 命名管道? - Unix FIFO 的有趣行为

如何使用 Unix(或 Windows)中的(最好是未命名的)管道将一个进程的标准输出发送到多个进程?

ffmpeg中的多个命名管道

可能的竞争条件,来自多个 tee 接收者的管道输出在 BASH 脚本中的命名管道上无序到达

如何从多个命名管道接收消息?