Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.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管道:在子管道结束之前从子管道读取的父管道_C_Fork_Pipe - Fatal编程技术网

C管道:在子管道结束之前从子管道读取的父管道

C管道:在子管道结束之前从子管道读取的父管道,c,fork,pipe,C,Fork,Pipe,下面的代码显示了子进程如何向管道端写入,然后父进程如何从另一端读取。 在我尝试代码之后,我注意到只有在子进程终止后父进程才能读取数据 有没有办法强迫父进程在名为write()的子进程之后立即到前台读取数据?有没有一种方法可以在不终止子进程的情况下读取数据 #include <stdio.h> /* For printf */ #include <string.h> /* For strlen */ #include <stdlib.h> /* For exit

下面的代码显示了子进程如何管道端写入,然后父进程如何从另一端读取。 在我尝试代码之后,我注意到只有在子进程终止后父进程才能读取数据

有没有办法强迫父进程在名为write()的子进程之后立即到前台读取数据?有没有一种方法可以在不终止子进程的情况下读取数据

#include <stdio.h> /* For printf */
#include <string.h> /* For strlen */
#include <stdlib.h> /* For exit */

#define READ 0 /* Read end of pipe */
#define WRITE 1 /* Write end of pipe */
char *phrase = "This is a test phrase.";
main(){
    int pid, fd[2], bytes;
    char message[100];

    if (pipe(fd) == -1) { /* Create a pipe */
        perror("pipe"); 
        exit(1); 
    }
    if ((pid = fork()) == -1) { /* Fork a child */
        perror("fork"); 
        exit(1); 
    }
    if (pid == 0) { /* Child, writer */
        close(fd[READ]); /* Close unused end */
        write(fd[WRITE], phrase, strlen(phrase)+1);
        close(fd[WRITE]); /* Close used end */
    } 
    else { /* Parent, reader */
        close(fd[WRITE]); /* Close unused end */
        bytes = read(fd[READ], message, sizeof(message));
        printf("Read %d bytes: %s\n", bytes, message);
        close(fd[READ]);  /* Close used end */
    }
}
#包括/*用于printf*/
#包括/*用于斯特伦*/
#包括/*用于退出*/
#定义读取0/*管道的读取端*/
#定义写入1/*管道的写入端*/
char*phrase=“这是一个测试短语。”;
main(){
int-pid,fd[2],字节;
字符消息[100];
如果(管道(fd)=-1){/*创建管道*/
佩罗(“管道”);
出口(1);
}
如果((pid=fork())==-1){/*fork是子对象*/
佩罗尔(“福克”);
出口(1);
}
如果(pid==0){/*子级,则写入程序*/
关闭(fd[读取];/*关闭未使用的端*/
书写(fd[write],短语,strlen(短语)+1);
关闭(fd[WRITE]);/*关闭已用端*/
} 
else{/*父级,读取器*/
关闭(fd[WRITE]);/*关闭未使用的端*/
字节=读取(fd[read],消息,sizeof(消息));
printf(“读取%d字节:%s\n”,字节,消息);
关闭(fd[读取]);/*关闭已用端*/
}
}

您不正确。在关闭“子”部分中管道的写入端并运行应用程序之前,尝试添加
sleep(120)
调用。

第一步可以使用一些同步技术完成。这意味着子级应该等到父级读取数据,或者父级在代码中终止。我在代码中添加了第二个管道,用于此同步

写入后的子级只是等待从该管道读取,并在读取中被阻止

函数read将仅在父级终止时返回(此处为0),因为现在read-in-child将获得文件结束通知,因为父级退出后管道的write-end-in-parent将关闭。 (写入端将在父级终止后自动关闭。我没有明确添加)

你的第二个要求

I also want the parent to read the data immediately after the child whites to
the pipe. 
为什么你认为这不会发生?总应该有一点小时差

#include <stdio.h> /* For printf */
#include <string.h> /* For strlen */
#include <stdlib.h> /* For exit */

#define READ 0 /* Read end of pipe */
#define WRITE 1 /* Write end of pipe */
char *phrase = "This is a test phrase.";
main(){
  int pid, fd[2], bytes;
  char message[100];
  int fd1[2];
  char buffer[1];
  int ret;

  if (pipe(fd) == -1) { /* Create a pipe */
    perror("pipe");
    exit(1);
  }
  if (pipe(fd1) == -1) { /* Create a pipe */
    perror("pipe");
    exit(1);
  }
  if ((pid = fork()) == -1) { /* Fork a child */
    perror("fork");
    exit(1);
  }
  if (pid == 0) { /* Child, writer */
    close(fd[READ]); /* Close unused end */
    close(fd1[WRITE]);/*Close write  end of the 2nd pipe*/
    write(fd[WRITE], phrase, strlen(phrase)+1);
    close(fd[WRITE]); /* Close used end */
    /*For synchronisation let the child try to
    read from the 2nd pipe. 
    The function read, will return 0 only when the
    parent terminates and in this we are
    not interested if at all anything read or not.
    The read statement below, will return only if the
    parent has terminated, thus ensures that the
    child terminates only after the parent*/
    ret = read(fd1[READ],buffer, 1);
  }

else { /* Parent, reader */
    close(fd[WRITE]); /* Close unused end */
    close(fd1[READ]); /*Close read end of the 2nd pipe*/
    bytes = read(fd[READ], message, sizeof(message));
    printf("Read %d bytes: %s\n", bytes, message);
    close(fd[READ]);  /* Close used end */

   }
}
#包括/*用于printf*/
#包括/*用于斯特伦*/
#包括/*用于退出*/
#定义读取0/*管道的读取端*/
#定义写入1/*管道的写入端*/
char*phrase=“这是一个测试短语。”;
main(){
int-pid,fd[2],字节;
字符消息[100];
int-fd1[2];
字符缓冲区[1];
int ret;
如果(管道(fd)=-1){/*创建管道*/
佩罗(“管道”);
出口(1);
}
如果(管道(fd1)=-1){/*创建管道*/
佩罗(“管道”);
出口(1);
}
如果((pid=fork())==-1){/*fork是子对象*/
佩罗尔(“福克”);
出口(1);
}
如果(pid==0){/*子级,则写入程序*/
关闭(fd[读取];/*关闭未使用的端*/
关闭(fd1[WRITE]);/*关闭第二个管道的写入端*/
书写(fd[write],短语,strlen(短语)+1);
关闭(fd[WRITE]);/*关闭已用端*/
/*为了同步,让孩子尝试
从第二根管子读。
函数read仅在
父母终止了,我们就在这里
不管你读不读,我都不感兴趣。
下面的read语句将仅在
父级已终止,因此确保
子项仅在父项之后终止*/
ret=读取(fd1[read],缓冲区,1);
}
else{/*父级,读取器*/
关闭(fd[WRITE]);/*关闭未使用的端*/
关闭(fd1[READ]);/*关闭第二个管道的读取端*/
字节=读取(fd[read],消息,sizeof(消息));
printf(“读取%d字节:%s\n”,字节,消息);
关闭(fd[读取]);/*关闭已用端*/
}
}

您应该初始化fd[0]=0和fd[1]=0

以下代码演示,在孩子写入管道后,家长可以读取管道。不需要子进程关闭管道或终止

#include <stdio.h> /* For printf */
#include <string.h> /* For strlen */
#include <stdlib.h> /* For exit */

#define READ 0 /* Read end of pipe */
#define WRITE 1 /* Write end of pipe */
char *phrase = "This is a test phrase.";
main(){
    int pid, fd[2], bytes;
    char message[100];

    if (pipe(fd) == -1) { /* Create a pipe */
        perror("pipe"); 
        exit(1); 
    }
    if ((pid = fork()) == -1) { /* Fork a child */
        perror("fork"); 
        exit(1); 
    }
    if (pid == 0) { /* Child, writer */
        close(fd[READ]); /* Close unused end */
        write(fd[WRITE], phrase, strlen(phrase)+1);
        sleep(10);
        close(fd[WRITE]); /* Close used end */
        sleep(20);
    } 
    else { /* Parent, reader */
        printf( "child ipd = %d\n\r", pid);
        close(fd[WRITE]); /* Close unused end */
        bytes = read(fd[READ], message, sizeof(message));
        printf("Read %d bytes: %s\n", bytes, message);
        close(fd[READ]);  /* Close used end */
        sleep(10);
    }
}
#包括/*用于printf*/
#包括/*用于斯特伦*/
#包括/*用于退出*/
#定义读取0/*管道的读取端*/
#定义写入1/*管道的写入端*/
char*phrase=“这是一个测试短语。”;
main(){
int-pid,fd[2],字节;
字符消息[100];
如果(管道(fd)=-1){/*创建管道*/
佩罗(“管道”);
出口(1);
}
如果((pid=fork())==-1){/*fork是子对象*/
佩罗尔(“福克”);
出口(1);
}
如果(pid==0){/*子级,则写入程序*/
关闭(fd[读取];/*关闭未使用的端*/
书写(fd[write],短语,strlen(短语)+1);
睡眠(10);
关闭(fd[WRITE]);/*关闭已用端*/
睡眠(20);
} 
else{/*父级,读取器*/
printf(“子ipd=%d\n\r”,pid);
关闭(fd[WRITE]);/*关闭未使用的端*/
字节=读取(fd[read],消息,sizeof(消息));
printf(“读取%d字节:%s\n”,字节,消息);
关闭(fd[读取]);/*关闭已用端*/
睡眠(10);
}
}

睡眠时间有点长,而你所需要做的就是拿出cpu,你不这么认为吗?简单地调用sched_yield()[假设在支持它的系统上运行,但是在其他系统上类似的东西]?给OP一段时间键入
ps
并点击enter键)怎么样?你是对的。你能查一下我贴的另一个问题吗?我的问题与本文中的问题相同,但如果我在关闭管道的写入端之前添加睡眠,则直到子管道终止,它才会读取。是否希望父对象等待子对象终止?因为您观察到的父级仅在子级终止后读取的情况可能不正确。我认为您观察到的是,在该程序终止后,您无法返回shell提示符。这可以通过确保父级