gpt4 book ai didi

UNIX 先进先出 : How to allow only one writer/reader pair to use a FIFO?

转载 作者:行者123 更新时间:2023-12-05 02:25:10 25 4
gpt4 key购买 nike

我写了两个程序:第一个是“writer”,它创建一个 FIFO 并将数据写入其中。第二个,“阅读器”在后台运行并在 FIFO 中查找数据。一旦数据存在,读取器就会将其读出。

如果我开始,例如两个写入器和两个读取器,他们都可以写入/读取同一个 FIFO。如何限制第 3 位和第 4 位读者/作者使用 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);


}

最佳答案

给定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);
}

关于UNIX 先进先出 : How to allow only one writer/reader pair to use a FIFO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2939065/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com