파이프를 사용하여 두 프로그램간에 간단한 문자열을 보내는 방법은 무엇입니까?


111

인터넷에서 검색해 보았지만 리소스가 거의 없습니다. 작은 예만으로도 충분합니다.

편집 내 말은 서로 통신하는 두 개의 다른 C 프로그램입니다. 한 프로그램은 "Hi"를 보내고 다른 프로그램은이를 받아야합니다. 그런 것.

c  unix  pipe 

1
아마도 당신은 같은 것을 의미하지 ls | grep ".o"않습니까? 아마도 당신이 의미하는 바에 대한 좀 더 많은 설명이 도움이 될 것입니다 ...
Jerry Coffin

13
이봐 요 ... 약간의 노력. 구글 "c 파이프 예제 코드". 첫 번째 결과는 정확합니다 : tldp.org/LDP/lpg/node11.html
Stephen

4
완전히 다른 두 프로그램 간의 커뮤니케이션을 원합니다. 나는 그것에 대한 자원을 찾을 수 없었다.

1
프로세스를 분기하지 않는 경우 "명명 된 파이프"를 살펴볼 필요가 있습니다.
Maygarden 판사

답변:


156

일반 파이프는 두 개의 관련 프로세스 만 연결할 수 있습니다. 프로세스에 의해 생성되며 마지막 프로세스가 닫을 때 사라집니다.

동작을 위해 FIFO라고도 하는 명명 된 파이프 는 관련되지 않은 두 프로세스를 연결하는 데 사용할 수 있으며 프로세스와 독립적으로 존재합니다. 아무도 사용하지 않아도 존재할 수 있음을 의미합니다. FIFO는 mkfifo()라이브러리 기능을 사용하여 생성 됩니다.

writer.c

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";

    /* create the FIFO (named pipe) */
    mkfifo(myfifo, 0666);

    /* write "Hi" to the FIFO */
    fd = open(myfifo, O_WRONLY);
    write(fd, "Hi", sizeof("Hi"));
    close(fd);

    /* remove the FIFO */
    unlink(myfifo);

    return 0;
}

reader.c

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAX_BUF 1024

int main()
{
    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    read(fd, buf, MAX_BUF);
    printf("Received: %s\n", buf);
    close(fd);

    return 0;
}

참고 : 단순화를 위해 위 코드에서 오류 검사가 생략되었습니다.


6
관련 프로세스 로 간주되는 것은 무엇입니까 ?
Pithikos 2014 년

7
하나 이상의 부모 / 자식 관계 (예 : 형제 포함)를 통해 관련된 프로세스 일 것입니다. 공통 조상은 파이프의 두 끝을 만들었을 것입니다. 관련없는 프로세스에는 공통 조상이 없습니다.
MSalters

4
독자가 먼저 시작하면 작동하지 않습니다. 빠른 수정은 open()리더를 루프 안에 넣는 것 입니다. 그러나 두 프로그램 예제를 제공하기 때문에 +1.
gsamaras 2014

이 예제는 Windows에서 작업하려면 약간의 조정이 필요합니까? unistd.h되는 POSIX 모든 ...
데이빗 칼슨

예, Windows 용 조정이 필요합니다. 명명 된 파이프에 대한 Wikipedia 기사에서는 Unix / Windows 차이점 중 일부에 대해 설명하고 빠른 Google 검색 이 Windows 구현에 도움이 될 수 있습니다.
jschmier 2015 년

41

에서 C로 파이프 만들기 ,이 쇼를 어떻게 파이프를 사용하는 프로그램을 포크합니다. fork ()를 원하지 않으면 명명 된 파이프를 사용할 수 있습니다 .

또한의 prog1 | prog2출력 prog1을 stdout 으로 보내고 stdinin에서 읽음 으로써 효과를 얻을 수 있습니다 prog2. 이름이 지정된 파일을 열어 stdin을 읽을 수도 있습니다 /dev/stdin(하지만 이식성이 확실하지 않음).

/*****************************************************************************
 Excerpt from "Linux Programmer's Guide - Chapter 6"
 (C)opyright 1994-1995, Scott Burkett
 ***************************************************************************** 
 MODULE: pipe.c
 *****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main(void)
{
        int     fd[2], nbytes;
        pid_t   childpid;
        char    string[] = "Hello, world!\n";
        char    readbuffer[80];

        pipe(fd);

        if((childpid = fork()) == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[0]);

                /* Send "string" through the output side of pipe */
                write(fd[1], string, (strlen(string)+1));
                exit(0);
        }
        else
        {
                /* Parent process closes up output side of pipe */
                close(fd[1]);

                /* Read in a string from the pipe */
                nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
                printf("Received string: %s", readbuffer);
        }

        return(0);
}

1
안녕 Stephen, 어쨌든이 코드를 두 가지 다른 기능에 사용할 수 있습니까? 파이프에 쓰는 것은 한 기능에서 수행되고 다른 기능에서 파이프를 읽는다는 의미입니까 ?? 이와 같은 작동 코드를 주시면 감사하겠습니다.
Mohsin 2016 년

8
dup2( STDIN_FILENO, newfd )

그리고 읽으십시오 :

char reading[ 1025 ];
int fdin = 0, r_control;
if( dup2( STDIN_FILENO, fdin ) < 0 ){
    perror( "dup2(  )" );
    exit( errno );
}
memset( reading, '\0', 1025 );
while( ( r_control = read( fdin, reading, 1024 ) ) > 0 ){
    printf( "<%s>", reading );
    memset( reading, '\0', 1025 );
}
if( r_control < 0 )
    perror( "read(  )" );    
close( fdin );    

하지만 fcntl더 나은 해결책이 될 수 있다고 생각합니다

echo "salut" | code

6

한 프로그램이 stdout에 쓰는 내용은 stdin을 통해 다른 프로그램에서 읽을 수 있습니다. 그래서 간단하게, C를 사용하여 작성 prog1하여 뭔가를 인쇄 printf()하고 prog2사용하여 뭔가를 읽을 scanf(). 그런 다음 실행

./prog1 | ./prog2

4

다음은 샘플입니다 .

int main()
{
    char buff[1024] = {0};
    FILE* cvt;
    int status;
    /* Launch converter and open a pipe through which the parent will write to it */
    cvt = popen("converter", "w");
    if (!cvt)
    {
        printf("couldn't open a pipe; quitting\n");
        exit(1)
    }
    printf("enter Fahrenheit degrees: " );
    fgets(buff, sizeof (buff), stdin); /*read user's input */
    /* Send expression to converter for evaluation */
    fprintf(cvt, "%s\n", buff);
    fflush(cvt);
    /* Close pipe to converter and wait for it to exit */
    status=pclose(cvt);
    /* Check the exit status of pclose() */
    if (!WIFEXITED(status))
        printf("error on closing the pipe\n");
    return 0;
}

이 프로그램의 중요한 단계는 다음과 같습니다.

  1. popen()자식 프로세스 및 상위의 관 사이의 연결을 확립 호.
  2. fprintf()자식 프로세스의 표준 입력에 쓰기로 일반 파일로 파이프를 사용하거나 통화는 표준 출력에서 읽습니다.
  3. pclose()파이프를 닫고 자식 프로세스를 종료 하는 호출입니다.

"컨버터"프로그램이 다른 프로그램이라는 것을 인정하지만이 예제는 질문의 요점을 놓친 것 같습니다. 첫 번째 의견은 형제 / 부모 / 두 번째 사촌 관계가없는 완전히 독립적 인 프로그램 간의 통신을 다룹니다.
cmm

2

첫째, 프로그램 1이 문자열을 쓰도록합니다 stdout(화면에 나타나기를 원하는 것처럼). 그런 다음 두 번째 프로그램은 stdin사용자가 키보드에서 입력하는 것처럼 에서 문자열을 읽어야합니다 . 그런 다음 실행합니다.

$ program_1 | program_2

1

이 답변은 미래의 Google 직원에게 도움이 될 수 있습니다.

#include <stdio.h>
#include <unistd.h>

int main(){     
     int p, f;  
     int rw_setup[2];   
     char message[20];      
     p = pipe(rw_setup);    
     if(p < 0){         
        printf("An error occured. Could not create the pipe.");  
        _exit(1);   
     }      
     f = fork();    
     if(f > 0){
        write(rw_setup[1], "Hi from Parent", 15);    
     }  
     else if(f == 0){       
        read(rw_setup[0],message,15);       
        printf("%s %d\n", message, r_return);   
     }  
     else{      
        printf("Could not create the child process");   
     }      
     return 0;

}

여기 에서 고급 양방향 파이프 호출 예제를 찾을 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.