2013-05-04 87 views
0

即时尝试使用管道将值从一个程序传递到另一个程序。将相同的管道定义为2个不同的程序

第一个程序创建一个管道,然后用fork创建一个子进程,并在子进程的部分使用execlp执行另一个程序。

我想从第一个程序发送字符到另一个,而他们与管道运行,但我不知道如何做到这一点,因为fd [2]只在第一个程序中定义。

的第一个节目的代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdbool.h> 
#include <termios.h> 
#include <signal.h> 

char getch(); 

int main() 
{ 
    bool selected; 
    int fd[2],pid; 
    char choice; 
    pipe(fd); 
    pid=fork(); 
    if(pid==0) 
    { 
     execlp("./draw.out", "draw.out", NULL); 
    } 
    else 
    { 
     do 
     { 
      choice=getch(); 
      close(fd[0]); 
      write(fd[1],&choice,1); 
      close(fd[1]); 
      kill(pid,SIGUSR2); 
     }while(choice!='q'); 

    } 

    return 1; 
    //getchar(); 

} 

第二程序的代码:

include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdbool.h> 
#include <signal.h> 


typedef struct 
{ 
    int x; 
    int y; 
}Point; 

typedef struct 
{ 
    Point dots[3]; 
}Tool; 

void drawBoard(int array[][20]); 
void initBoard(int array[][20]); 
Tool retrieveTool(); 
bool changeLocation(int array[][20],Tool* tool); 
void my_handler(int signum); 

int main() 
{ 
    bool nextTool=true; 
    Tool temp=retrieveTool(); 
    int gameBoard[20][20]; 
    signal(SIGUSR2, my_handler); 
    initBoard(gameBoard); 
    changeLocation(gameBoard,&temp); 
    drawBoard(gameBoard); 
    while(true) 
    { 
     sleep(1); 
     system("clear"); 
     if(!changeLocation(gameBoard,&temp)) 
      temp=retrieveTool(); 
     drawBoard(gameBoard); 
    } 
    return 1; 
    //getchar(); 

} 

void my_handler(int signum) 
{ 
    char geth='a'; 
    if (signum == SIGUSR2) 
    { 


    close(fd[1]); 
    read(fd[0],&geth,1); 
    close(fd[0]); 

    printf("Received SIGUSR2!%c\n",geth); 
    } 
} 

正如你可以在第一节目中看到我限定FD [2 ]变量,并且我从用户发送一个字符到管道。 我希望其他程序中的信号处理程序“my_handler”将从同一个管道读取,但fd在此处未定义(在第二个程序中)。

我该怎么做?

回答

1

虽然管道变量fd只在父级中,但实际的文件描述符是共享的。只要你的程序知道它们是什么(作为整数),就可以使用它们。因此,有几个选项

  1. 传递文件描述符到孩子计划在exec调用(所以像

    的sprintf(BUF1, “%d”,FD [0]);

    execlp( “./ draw.out”, “draw.out”, “-in”,BUF1,NULL);

    然后读取的argv描述符在拉伸

  2. 甲。第二,相当普遍,选项我s使用fd 0输入和fd 1输出的约定。这只适用于你的子程序没有使用stdin(或std :: cin)的情况。否则,你可以选择另一个你确定可用的描述符(这比听起来更难)。为此,您需要在fork之后但在exec之前复制描述符。类似于

    dup2(fd [0],0);

    close(fd [0]);

    close(fd [1]); //这个孩子并不需要FD [1]

    execlp(....)

在你需要确保任何未使用的描述,包括旧副本,关闭掉所有的情况。我建议尽快完成关闭呼叫(在叉后的每个块的开始处)。否则,程序将不会在描述符上遇到EOF。顺便说一句,你的程序都是关闭描述符或者循环或者可以被多次调用的处理程序 - 两者都不可能是正确的。您应该从读,写和关闭中检查返回值以帮助调试。

相关问题