[英]how to establish a non blocking read from unix pipes?
假設我們有一個 pipe int InPipe[2];
. 在讀取整個可用數據輸入時,如何讀取輸入直到 pipe 為空而不阻塞?
我知道這個問題已經被問過好幾次了,但我無法組裝合適的 function。
到目前為止,這是我的代碼:
int InPipe[2];
char buffer[1024];
int rc;
while (true){
read(InPipe[0], buffer, sizeof(buffer));
fprintf(stdout, “%s“, buffer);
bzero(&buffer, sizeof(buffer)); // Clearing Buffer
}
任何想法、建議、代碼片段
從 pipe 讀取
嘗試從當前為空
block
的pipe
讀取,直到至少一個字節已寫入pipe
。 如果 pipe 的寫結束被關閉,則從 pipe 讀取的進程將在讀取pipe
中的所有剩余數據后看到end-of-file
(即read()
返回 0)。
取自 linux 接口編程。
你不能。 在這種情況下,從 pipe 讀取的進程將被阻止。
由於人們的評論,我添加了這個部分:
我們可以使用pipe
來允許兩個進程之間的通信。 為了使用 pipe 連接兩個進程,我們在pipe()
調用之后調用fork()
。 在fork()
之后,一個進程立即關閉 pipe 的寫端描述符,另一個進程關閉讀端的描述符。 例如,如果父級要向子級發送數據,那么它將關閉其對 pipe 的讀取描述符, filedes[0]
,而子級將關閉其對 pipe 的寫入描述符, filedes[1]
,然后代碼這將是:
int filedes[2];
if (pipe(filedes) == -1) /* Create the pipe */
errExit("pipe");
switch (fork()) /* Create a child process */
{
case -1:
errExit("fork");
case 0: /* Child */
if (close(filedes[1]) == -1) /* Close unused write end */
errExit("close");
/* Child now reads from pipe */
break;
default: /* Parent */
if (close(filedes[0]) == -1) /* Close unused read end */
errExit("close");
/* Parent now writes to pipe */
break;
}
評論中提到了一些關鍵的事情,即非阻塞 IO,並在自己的線程中執行讀取,以及其他一些建議。 這里的例子詳細解釋了它的架構。 下面只復制了代碼部分,因為我相信它是其中幾個評論的一個很好的說明。 示例代碼自始至終都有注釋。 閱讀它們,它們是一個很好的教程:
// C program to demonstrate use of fork() and pipe()
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<sys/wait.h>
int main()
{
// We use two pipes
// First pipe to send input string from parent
// Second pipe to send concatenated string from child
int fd1[2]; // Used to store two ends of first pipe
int fd2[2]; // Used to store two ends of second pipe
char fixed_str[] = "forgeeks.org";
char input_str[100];
pid_t p;
if (pipe(fd1)==-1)
{
fprintf(stderr, "Pipe Failed" );
return 1;
}
if (pipe(fd2)==-1)
{
fprintf(stderr, "Pipe Failed" );
return 1;
}
scanf("%s", input_str);
p = fork(); //Note - the return of fork can be less than, greater
// than or equal to zero. Each is significant in
// knowing how to direct program flow, as shown
// in this section...
if (p < 0)
{
fprintf(stderr, "fork Failed" );
return 1;
}
// Parent process
else if (p > 0)
{
char concat_str[100];
close(fd1[0]); // Close reading end of first pipe
// Write input string and close writing end of first
// pipe.
write(fd1[1], input_str, strlen(input_str)+1);
close(fd1[1]);
// Wait for child to send a string
wait(NULL);
close(fd2[1]); // Close writing end of second pipe
// Read string from child, print it and close
// reading end.
read(fd2[0], concat_str, 100);
printf("Concatenated string %s\n", concat_str);
close(fd2[0]);
}
// child process
else
{
close(fd1[1]); // Close writing end of first pipe
// Read a string using first pipe
char concat_str[100];
read(fd1[0], concat_str, 100);
// Concatenate a fixed string with it
int k = strlen(concat_str);
int i;
for (i=0; i<strlen(fixed_str); i++)
concat_str[k++] = fixed_str[i];
concat_str[k] = '\0'; // string ends with '\0'
// Close both reading ends
close(fd1[0]);
close(fd2[0]);
// Write concatenated string and close writing end
write(fd2[1], concat_str, strlen(concat_str)+1);
close(fd2[1]);
exit(0);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.