Presumivelmente, você não quer dizer algo como ls | grep ".o"? Talvez um pouco mais de explicação do que você quis dizer ajudasse ...
Jerry Coffin
13
Vamos cara ... um pouco de esforço. Google "código de exemplo de tubos c". O primeiro resultado é exato: tldp.org/LDP/lpg/node11.html
Stephen
4
Eu quero a comunicação entre dois programas completamente diferentes. Não consegui encontrar um recurso para isso.
1
Se você não estiver bifurcando um processo, precisará examinar os "canais nomeados".
Juiz Maygarden
Respostas:
156
Um tubo regular pode conectar apenas dois processos relacionados. Ele é criado por um processo e desaparecerá quando o último processo o fechar.
Um pipe nomeado , também chamado de FIFO por seu comportamento, pode ser usado para conectar dois processos não relacionados e existe independentemente dos processos; o que significa que pode existir mesmo se ninguém o estiver usando. Um FIFO é criado usando a mkfifo()função de biblioteca.
Exemplo
escritor.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);return0;}
reader.c
#include<fcntl.h>#include<stdio.h>#include<sys/stat.h>#include<unistd.h>#define MAX_BUF 1024int 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);return0;}
Nota: A verificação de erros foi omitida do código acima para simplificar.
Provavelmente processos relacionados por meio de uma ou mais relações pai / filho (por exemplo, inclui irmãos). O ancestral comum teria criado as duas extremidades do tubo. Processos não relacionados carecem desse ancestral comum.
MSalters
4
Isso não funcionará se o leitor começar primeiro. Uma solução rápida seria colocar o open()do leitor dentro de um loop. No entanto, +1 porque você fornece um exemplo de dois programas.
gsamaras de
Presumo que este exemplo precisa de alguns ajustes para funcionar no Windows? unistd.h sendo POSIX e tudo ...
Em Criando tubos em C , mostra como bifurcar um programa para usar um tubo. Se você não quiser fazer um fork (), pode usar canais nomeados .
Além disso, você pode obter o efeito de prog1 | prog2enviando a saída de prog1para stdout e lendo de stdindentro prog2. Você também pode ler stdin abrindo um arquivo chamado /dev/stdin(mas não tenho certeza da portabilidade disso).
/*****************************************************************************
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);}
Ei Stephen, mesmo assim posso usar este código para duas funções diferentes? o que significa que a escrita no pipe é feita em uma função e a leitura do pipe em outra função ?? um código funcional como este seria apreciado.
O que um programa grava em stdout pode ser lido por outro via stdin. Então, simplesmente, usando c, escreva prog1para imprimir algo usando printf()e prog2para ler algo usando scanf(). Então é só correr
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");return0;}
As etapas importantes neste programa são:
A popen()chamada que estabelece a associação entre um processo filho e um pipe no pai.
A fprintf()chamada que usa o pipe como um arquivo comum para gravar no stdin do processo filho ou ler em seu stdout.
A pclose()chamada que fecha o pipe e faz com que o processo filho seja encerrado.
Eu acho que este exemplo perde o ponto da questão, embora eu admita que o programa "conversor" seja um programa diferente. O primeiro comentário aborda a comunicação entre programas completamente independentes que não têm uma relação irmão / pai / primo em segundo grau.
cmm
2
Primeiro, faça com que o programa 1 escreva a string stdout(como se você gostaria que ela aparecesse na tela). Em seguida, o segundo programa deve ler uma string de stdin, como se um usuário estivesse digitando em um teclado. então você executa:
Esta resposta pode ser útil para um futuro Googler.
#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);}elseif(f ==0){
read(rw_setup[0],message,15);
printf("%s %d\n", message, r_return);}else{
printf("Could not create the child process");}return0;}
Você pode encontrar um exemplo avançado de chamada de tubo bidirecional aqui .
ls | grep ".o"
? Talvez um pouco mais de explicação do que você quis dizer ajudasse ...Respostas:
Um tubo regular pode conectar apenas dois processos relacionados. Ele é criado por um processo e desaparecerá quando o último processo o fechar.
Um pipe nomeado , também chamado de FIFO por seu comportamento, pode ser usado para conectar dois processos não relacionados e existe independentemente dos processos; o que significa que pode existir mesmo se ninguém o estiver usando. Um FIFO é criado usando a
mkfifo()
função de biblioteca.Exemplo
escritor.c
reader.c
Nota: A verificação de erros foi omitida do código acima para simplificar.
fonte
open()
do leitor dentro de um loop. No entanto, +1 porque você fornece um exemplo de dois programas.Em Criando tubos em C , mostra como bifurcar um programa para usar um tubo. Se você não quiser fazer um fork (), pode usar canais nomeados .
Além disso, você pode obter o efeito de
prog1 | prog2
enviando a saída deprog1
para stdout e lendo destdin
dentroprog2
. Você também pode ler stdin abrindo um arquivo chamado/dev/stdin
(mas não tenho certeza da portabilidade disso).fonte
E leia:
Mas, acho que
fcntl
pode ser uma solução melhorfonte
O que um programa grava em stdout pode ser lido por outro via stdin. Então, simplesmente, usando c, escreva
prog1
para imprimir algo usandoprintf()
eprog2
para ler algo usandoscanf()
. Então é só correrfonte
Aqui está um exemplo :
As etapas importantes neste programa são:
popen()
chamada que estabelece a associação entre um processo filho e um pipe no pai.fprintf()
chamada que usa o pipe como um arquivo comum para gravar no stdin do processo filho ou ler em seu stdout.pclose()
chamada que fecha o pipe e faz com que o processo filho seja encerrado.fonte
Primeiro, faça com que o programa 1 escreva a string
stdout
(como se você gostaria que ela aparecesse na tela). Em seguida, o segundo programa deve ler uma string destdin
, como se um usuário estivesse digitando em um teclado. então você executa:fonte
Esta resposta pode ser útil para um futuro Googler.
Você pode encontrar um exemplo avançado de chamada de tubo bidirecional aqui .
fonte