C 为两个不同的程序定义相同的管道

C 为两个不同的程序定义相同的管道,c,signals,fork,pipe,file-descriptor,C,Signals,Fork,Pipe,File Descriptor,我正在尝试使用管道将值从一个程序传递到另一个程序 第一个程序创建一个管道,然后使用fork创建一个子进程,在子进程部分,她使用execlp执行另一个程序 我想在第一个程序与管道一起运行时将字符从第一个程序发送到另一个程序,但我不知道如何做,因为fd[2]仅在第一个程序中定义 第一个程序的代码: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdbool.h>

我正在尝试使用管道将值从一个程序传递到另一个程序

第一个程序创建一个管道,然后使用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();

}
#包括
#包括
#包括
#包括
#包括
#包括
char getch();
int main()
{
选择布尔;
int-fd[2],pid;
字符选择;
管道(fd);
pid=fork();
如果(pid==0)
{
execlp(“./draw.out”,“draw.out”,NULL);
}
其他的
{
做
{
choice=getch();
关闭(fd[0]);
写入(fd[1],&choice,1);
关闭(fd[1]);
杀死(pid,SIGUSR2);
}while(choice!='q');
}
返回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);
    }
}
#

包括
#包括
#包括
#包括
#包括
类型定义结构
{
int x;
int-y;
}点;
类型定义结构
{
点点[3];
}工具;
空心抽油板(int数组[][20]);
void initBoard(int数组[][20]);
工具检索工具();
bool-changeLocation(int-array[][20],Tool*Tool);
无效我的_处理程序(int signum);
int main()
{
bool nextTool=true;
工具温度=检索工具();
int gameBoard[20][20];;
信号(SIGUSR2,我的_处理器);
初始化板(游戏板);
更改位置(游戏板和临时);
抽板(游戏板);
while(true)
{
睡眠(1);
系统(“清除”);
如果(!更改位置(游戏板和临时))
temp=检索工具();
抽板(游戏板);
}
返回1;
//getchar();
}
无效my_处理程序(int signum)
{
chargeth='a';
if(signum==SIGUSR2)
{
关闭(fd[1]);
读取(fd[0],&geth,1);
关闭(fd[0]);
printf(“收到的信号!%c\n”,geth);
}
}
正如您在第一个程序中所看到的,我将fd[2]变量定义到管道,并将一个字符从用户发送到管道。 我希望另一个程序上的信号处理程序“my_handler”将从同一管道中读取,但是这里没有定义fd(在第二个程序中)


我应该怎么做?

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

  • 在exec调用中将描述符号传递给子程序(例如

    sprintf(buf1,“%d”,fd[0])

    execlp(“./draw.out”、“draw.out”、“-in”、buf1,空)

    然后从绘图中的argv读取描述符

  • 第二个相当常见的选项是使用fd 0为输入,fd 1为输出的约定。这仅在您的子程序不使用stdin(或std::cin)的情况下有效。否则,您可以选择另一个您确信可用的描述符(这比听起来更难)。要使其工作,您需要在fork之后但在exec之前复制描述符。类似于

    dup2(fd[0],0)

    关闭(fd[0])

    close(fd[1]);//孩子不需要fd[1]

    execlp(…)

  • 在所有情况下,您都需要确保关闭所有未使用的描述符,包括旧副本。我建议尽快执行关闭调用(在fork之后的每个块的开头)。否则,您的程序将不会在描述符上遇到EOF。顺便说一句,您的程序都在循环或可多次调用的处理程序中关闭描述符-两者都不可能正确。您应该检查读取、写入和关闭的返回值,以帮助调试