我寫了兩個程序:第一個是「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