我写了两个程序:第一个是“writer”,它创建一个FIFO并将数据写入其中。第二个,“读者”在后台运行并在FIFO中查找数据。一旦有数据,读者就会读出来。UNIX FIFO:如何仅允许一个写入器/读取器对使用FIFO?
如果我开始例如两个编写者和两个读者,他们都可以写入/读入/来自同一个FIFO。如何限制第三和第四个读写器使用FIFO,并且只允许一个写入器和一个读取器使用FIFO?
我写了两个程序:第一个是“writer”,它创建一个FIFO并将数据写入其中。第二个,“读者”在后台运行并在FIFO中查找数据。一旦有数据,读者就会读出来。UNIX FIFO:如何仅允许一个写入器/读取器对使用FIFO?
如果我开始例如两个编写者和两个读者,他们都可以写入/读入/来自同一个FIFO。如何限制第三和第四个读写器使用FIFO,并且只允许一个写入器和一个读取器使用FIFO?
使用pipe(2)
创建FIFO,并且仅当FIFO从父进程派生出来时,才将FIFO的每一端的文件描述符提供给适当的进程。 (或者,让读者呼叫pipe(2)
并分配作者,反之亦然。)由于FIFO永远不会存在于文件系统中,所以其他任何进程都无法访问它。
如果您必须使用已命名的FIFO,请在读取器和写入器打开后删除FIFO。只要阅读器和书写器将其打开,底层的FIFO仍然存在,但没有新的进程能够打开它。但是,在删除它之前,会有另一个读写器可能会打开FIFO的竞争状况。
FIFO编剧:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define BUFFERSIZE 50
#define CHMOD 0777
int main(int argc, char **argv)
{
char outbuf[BUFFERSIZE]; // outbuffer
int fifo, j, anzahl;
// fifo - pipe file deskriptor, j - counter, anzahl - Parameter.
if(argc!=2) // Check if parameter is ok
{
printf("Ungültiger Parameter! Bsp.: ./fifow 10\n");
return 1;
}
anzahl=atoi(argv[1]); // convert paramter to integer
mkfifo("namedpipe4", CHMOD); // make FIFO "namedpipe4"
fifo = open("namedpipe4",O_WRONLY); // open FIFO
//
for(j=0;j<anzahl;j++)
{
printf("Writer PID: %d writes record nr. %6d\n", getpid(), j+1);
sprintf(outbuf, "Writer PID: %d writes record nr. %6d\n", getpid(), j+1);
write(fifo, outbuf, BUFFERSIZE);
remove("namedpipe4"); // removing the fifo
sleep(1); // Wait 1 sec
}
close(fifo); //
exit(0);
}
FIFO读者:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define BUFFERSIZE 50
int main(void)
{
char inbuf[BUFFERSIZE]; // inbuffer
int fifo, var;
printf("\n Waiting for a Pipe....\n");
while((fifo = open("namedpipe4",O_RDONLY)) == -1) // while "there is no such pipe"
{
remove("namedpipe4");
sleep(1);
}
while((var = read(fifo, inbuf, BUFFERSIZE)) > 0) // while "i can read"
{
printf("Reader PID: %d reads record: %s\n", getpid(), inbuf);
sleep(1);
}
close(fifo); //
printf("\n EOF..\n");
exit(0);
}
为了将来的参考,您可以随时在发布后编辑您的问题(而不是发布更新作为您的问题的答案,这是各种语义差的问题) – jasonmp85 2010-05-31 10:40:24
鉴于the code you posted in a separate answer,这里是一个修改版本,修复您遇到的问题。详情请参阅评论:
mkfifo
以检查是否有另一个写入程序已经创建了管道。flock
获取专用咨询锁,以避免第二个读卡器在第一个读卡器删除之前打开管道的竞争状况。编剧:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h> /* needed for mkfifo */
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define BUFFERSIZE 50
#define CHMOD 0777
int
main (int argc, char **argv)
{
char outbuf[BUFFERSIZE];
int fifo, j, anzahl;
if (argc != 2)
{
printf("Ungültiger Parameter! Bsp.: ./fifow 10\n");
return 1;
}
anzahl=atoi(argv[1]);
/* mkfifo fails if the file already exists, which means there's a
* writer waiting for a reader. This assures that only one writer
* will write to the pipe, since it only opens the pipe if it was
* the one who created it.
*/
if (mkfifo("namedpipe4", CHMOD) == -1)
{
printf("namedpipe4 already exists\n");
return 1;
}
fifo = open("namedpipe4", O_WRONLY);
for (j = 0; j < anzahl; j++)
{
printf("Writer PID: %d writes record nr. %6d\n", getpid(), j + 1);
sprintf(outbuf, "Writer PID: %d writes record nr. %6d\n", getpid(), j + 1);
write(fifo, outbuf, BUFFERSIZE);
remove("namedpipe4");
sleep(1);
}
close(fifo);
exit(0);
}
读者:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h> /* for flock */
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#define BUFFERSIZE 50
int
main (int argc, char **argv)
{
char inbuf[BUFFERSIZE];
int fifo, var;
printf("\n Waiting for a Pipe....\n");
/* There are *two* ways the open can fail: the pipe doesn't exist
* yet, *or* it succeeded, but a different writer already opened
* it but didn't yet remove it.
*/
while (1)
{
while ((fifo = open("namedpipe4", O_RDONLY)) == -1)
{
/* Since you didn't specify O_CREAT in the call to open, there
* is no way that namedpipe4 would have been created by the
* reader. If there *is* now a namedpipe4, a remove here
* would delete the one the writer created!
*/
sleep(1);
}
/* Get an exclusive lock on the file, failing if we can't get
* it immediately. Only one reader will succeed.
*/
if (flock (fifo, LOCK_EX | LOCK_NB) == 0)
break;
/* We lost the race to another reader. Give up and wait for
* the next writer.
*/
close (fifo);
}
/* We are definitely the only reader.
*/
/* *Here* we delete the pipe, now that we've locked it and thus
* know that we "own" the pipe. If we delete before locking,
* there's a race where after we opened the pipe, a different
* reader also opened, deleted, and locked the file, and a new
* writer created a new pipe; in that case, we'd be deleting the
* wrong pipe.
*/
remove("namedpipe4");
while ((var = read(fifo, inbuf, BUFFERSIZE)) > 0)
{
printf("Reader PID: %d reads record: %s\n", getpid(), inbuf);
/* No need to sleep; we'll consume input as it becomes
* available.
*/
}
close(fifo);
printf("\n EOF..\n");
exit(0);
}
非常感谢你们,保罗!它看起来像它的作品。 我必须使用命名管道(FIFO),所以我只是添加一个删除(“namedpipe”);在读者程序中的write()语句后面。 现在,如果我启动2个作者和2个阅读器,只有1个作者可以编写,只有1个阅读器可以阅读。 – 2010-05-30 15:45:21
大声笑,有时它的作品,有时不,不知道为什么... – 2010-05-30 16:25:03
@ Max Krug:定义“不工作”。 – 2010-05-30 16:53:11