簡體   English   中英

如何從 unix 管道建立非阻塞讀取?

[英]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 讀取

嘗試從當前為空blockpipe讀取,直到至少一個字節已寫入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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM