Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C linux中使用管道的双向通信_C_Linux_Pipe_Communication_Fgets - Fatal编程技术网

C linux中使用管道的双向通信

C linux中使用管道的双向通信,c,linux,pipe,communication,fgets,C,Linux,Pipe,Communication,Fgets,我希望父进程和子进程在C linux中使用管道进行通信。首先,我希望家长传递一个字符串,然后孩子确认它。我创建了两个文件描述符。一个用于父子关系,即readpipe,另一个用于viceversa的WritePie。问题是它没有把我的数据作为输入。此外,我希望printf语句(如“enteryourdata”)打印一次,但由于fork之后有两个进程,因此它们将显示两次。还有其他选择吗 //readpipe[0] = child read //readpipe[1]= parent write

我希望父进程和子进程在C linux中使用管道进行通信。首先,我希望家长传递一个字符串,然后孩子确认它。我创建了两个文件描述符。一个用于父子关系,即readpipe,另一个用于viceversa的WritePie。问题是它没有把我的数据作为输入。此外,我希望printf语句(如“enteryourdata”)打印一次,但由于fork之后有两个进程,因此它们将显示两次。还有其他选择吗

 //readpipe[0] = child read
 //readpipe[1]= parent write

//writepipe[0]=parent read
//writepipe[1]=child write

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

 int main(void)
 {
      pid_t pid;
      int r;
      /* Hope this is big enough. */
     char buf[1024];
     char cp[50];
     char ans;
     int readpipe[2];
     int writepipe[2];
     int a;
     int b;
     a=pipe(readpipe);
     b=pipe(writepipe);
     if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
     if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }

     printf("\nSEND SOMETHING TO CHILD PROCESS\t");
     scanf(" %c",&ans);
     pid=fork();
     if(pid==-1)
     {
         printf("pid:main");
         exit(1);
     }

     while(ans=='y' || ans=='Y')
     {
        printf("\nEnter data\t"); //printed twice
        fgets(cp, 50, stdin);     //not taking data
        printf("\n%s",cp);        
        if(pid==0)
        { //CHILD PROCESS
         close(readpipe[1]);
         close(writepipe[0]);
         read(readpipe[0],buf,sizeof(buf));
         printf("\nSENT\n %s",buf);
         write(writepipe[1],cp,strlen(cp)+1);
       }
      else
      { //PARENT PROCESS
        close(readpipe[0]);
        close(writepipe[1]);
        write(readpipe[1],cp,strlen(cp)+1);
        read(writepipe[0],buf,sizeof(buf));
        printf("\nRECEIVED\n %s",buf);
     }
     printf("\nSEND SOMETHING TO CHILD PROCESS\t");
     scanf(" %c",&ans);
  }
  close(readpipe[1]);
  close(writepipe[0]);
  close(readpipe[0]);
  close(writepipe[1]);

   return 0;
}
//readpipe[0]=子读取
//readpipe[1]=父写入
//WritePie[0]=父级读取
//WritePie[1]=子写入
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
pid_t pid;
INTR;
/*希望这个足够大*/
char-buf[1024];
char-cp[50];
查尔安斯;
int readpipe[2];
int writepe[2];
INTA;
int b;
a=管道(读取管道);
b=管道(可写实体);
如果(a==-1){perror(“管道”);退出(退出失败)}
如果(b=-1){perror(“管道”);退出(退出失败)}
printf(“\n将某物发送到子进程\t”);
scanf(“%c”和“&ans”);
pid=fork();
如果(pid==-1)
{
printf(“pid:main”);
出口(1);
}
而(ans=='y'| ans=='y')
{
printf(“\n输入数据\t”);//打印两次
fgets(cp,50,stdin);//不获取数据
printf(“\n%s”,cp);
如果(pid==0)
{//子进程
关闭(读取管道[1]);
关闭(writepe[0]);
read(readpipe[0],buf,sizeof(buf));
printf(“\n发送\n%s”,buf);
write(writepe[1],cp,strlen(cp)+1);
}
其他的
{//父进程
关闭(读取管道[0]);
关闭(writepe[1]);
写入(readpipe[1],cp,strlen(cp)+1);
read(writepe[0],buf,sizeof(buf));
printf(“\n收到\n%s”,buf);
}
printf(“\n将某物发送到子进程\t”);
scanf(“%c”和“&ans”);
}
关闭(读取管道[1]);
关闭(writepe[0]);
关闭(读取管道[0]);
关闭(writepe[1]);
返回0;
}
您呼叫

    printf("\nEnter data\t"); //printed twice
    fgets(cp, 50, stdin);     //not taking data
在检查您是在父进程中还是在子进程中之前。当然,这会导致两个进程都打印并读取表单标准输入。所以不清楚哪个进程读取您键入的日期

同样的问题也会出现在这些线路中:

 printf("\nSEND SOMETHING TO CHILD PROCESS\t");
 scanf(" %c",&ans);
我建议您重新设计程序,以便将父进程中运行的代码与子进程中运行的代码清楚地分开

  • 为什么fgets不采集数据? 在第一次扫描中,您正在读取单个字符,新行仍将处于
    输入缓冲区,这样做将导致跳过

    要解决此问题,您应该使用scanf(“%[^\n]%*c”、&ans)- 有关更多详细信息,请参阅

  • 查找修改后的代码。。这可能对您有帮助(在我做了一些更改并验证了基本功能的同时中断)

  • 内部主(空) {

    pid\u t pid;
    INTR;
    /*希望这个足够大*/
    char-buf[1024];
    char-cp[50];
    查尔安斯;
    int readpipe[2];
    int writepe[2];
    INTA;
    int b;
    a=管道(读取管道);
    b=管道(可写实体);
    如果(a==-1){perror(“管道”);退出(退出失败)}
    如果(b=-1){perror(“管道”);退出(退出失败)}
    printf(“\n将某物发送到子进程\t”);
    scanf(“%[^\n]%*c”和&ans);
    //ans=getchar();
    fflush(stdin);
    pid=fork();
    如果(pid==-1)
    {
    printf(“pid:main”);
    出口(1);
    }
    而(ans=='y'| ans=='y')
    {
    如果(pid==0)
    { 
    //子进程
    关闭(读取管道[1]);
    关闭(writepe[0]);
    if(读取(readpipe[0],buf,sizeof(buf))<0)
    {
    打破
    }
    printf(“\n归档进程读取:%s\n”,buf);
    printf(“\n(子)输入数据:\t”);//打印两次
    fgets(cp,50,stdin);//不获取数据
    printf(“\n写入父级%s的数据”,cp);
    如果(!strncmp(“Q”,cp,1)| | write(writepie[1],cp,strlen(cp)+1)<0)
    {
    打破
    }
    }
    其他的
    { 
    //父进程
    关闭(读取管道[0]);
    关闭(writepe[1]);
    printf(“\n(父级)输入数据\t”);//打印两次
    fgets(cp,50,stdin);//不获取数据
    printf(“\n写入子项的数据:%s”,cp);
    如果(!strncmp(“Q”,cp,1)|写(readpipe[1],cp,strlen(cp)+1)<0)
    {
    打破
    }        
    if(读(写Epipe[0],buf,sizeof(buf))<0)
    {
    打破
    }
    printf(“\n租进程读取:%s\n”,buf);
    }
    ans='y';
    }
    关闭(读取管道[1]);
    关闭(writepe[0]);
    关闭(读取管道[0]);
    关闭(writepe[1]);
    返回0;
    

    }

    如果您不使用多路复用,例如,您可能会因相互饥饿而出现死锁(每个进程都被阻塞,等待另一个进程的某些输出)。谢谢,先生。但是你能告诉我一些关于strncmp的功能吗。程序中的“Q”是什么?为什么在这里使用它?我添加了这个逻辑来中断while循环,如果输入Q,则strncmp将通过,它将中断while循环并退出程序。。如果它不干净。。你可以选择更好的方法。。
    pid_t pid;
    int r;
    /* Hope this is big enough. */
    char buf[1024];
    char cp[50];
    char ans;
    int readpipe[2];
    int writepipe[2];
    int a;
    int b;
    a=pipe(readpipe);
    b=pipe(writepipe);
    if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
    if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }
    
    printf("\nSEND SOMETHING TO CHILD PROCESS\t");
    scanf("%[^\n]%*c",&ans);
    //ans = getchar();
    fflush(stdin);
    pid=fork();
    if(pid==-1)
    {
        printf("pid:main");
        exit(1);
    }
    
    while(ans=='y' || ans=='Y')
    {
        if(pid==0)
        { 
            //CHILD PROCESS
            close(readpipe[1]);
            close(writepipe[0]);
            if(read(readpipe[0],buf,sizeof(buf)) < 0)
            {
                break;
            }
    
            printf("\nChild Process Read: %s\n",buf);
    
            printf("\n(child)Enter data:\t"); //printed twice
            fgets(cp, 50, stdin);     //not taking data
            printf("\nData Written to Parent%s",cp);
            if(!strncmp("Q",cp,1) || write(writepipe[1],cp,strlen(cp)+1) < 0)
            {
                break;
            }
        }
        else
        { 
            //PARENT PROCESS
            close(readpipe[0]);
            close(writepipe[1]);
            printf("\n(Parent)Enter data\t"); //printed twice
            fgets(cp, 50, stdin);     //not taking data
    
            printf("\nData Writtent to Child: %s",cp);
            if(!strncmp("Q",cp,1) || write(readpipe[1],cp,strlen(cp)+1) < 0)
            {
                break;
            }        
    
            if(read(writepipe[0],buf,sizeof(buf)) < 0)
            {
                break;
            }
            printf("\nParent Process Read: %s\n",buf);
        }
        ans ='y';
    }
    
    close(readpipe[1]);
    close(writepipe[0]);
    close(readpipe[0]);
    close(writepipe[1]);
    return 0;