C 在一个过程中写一些东西,在另一个过程中读它

C 在一个过程中写一些东西,在另一个过程中读它,c,fork,C,Fork,我想在进程A中写一些东西,在进程B中读它,进程B由A分叉。但我发现,除非A终止,否则B无法读取内容。如何在进程A中写入而在进程B中读取而不退出?我的代码如下 #include <stdio.h> #include <unistd.h> int mypipe[2]; int main(){ FILE* f; pid_t pid = 0; int num = 0, temp; pipe(mypipe); pid = fork()

我想在进程A中写一些东西,在进程B中读它,进程B由A分叉。但我发现,除非A终止,否则B无法读取内容。如何在进程A中写入而在进程B中读取而不退出?我的代码如下

#include <stdio.h>
#include <unistd.h>

int mypipe[2];

int main(){
    FILE* f;
    pid_t pid = 0;
    int num = 0, temp;

    pipe(mypipe);

    pid = fork();

    if (pid == (pid_t)0){
        f = fdopen(mypipe[0], "r");
        while (1){
            fscanf(f, "%d", &temp);
            printf("from child: %d\n", temp);
        }
        fclose(f);
    }
    else{
        f = fdopen(mypipe[1], "w");
        while (1){
            scanf("%d", &num);
            fprintf(f, "%d\n", num);
            //break;
        }
        fclose(f);
    }

    return 0;
}
#包括
#包括
int mypipe[2];
int main(){
文件*f;
pid_t pid=0;
int num=0,温度;
管道(mypipe);
pid=fork();
如果(pid==(pid_t)0){
f=fdopen(mypipe[0],“r”);
而(1){
fscanf(f、%d、&temp);
printf(“来自子项:%d\n”,temp);
}
fclose(f);
}
否则{
f=fdopen(mypipe[1],“w”);
而(1){
scanf(“%d”和&num);
fprintf(f,“%d\n”,num);
//中断;
}
fclose(f);
}
返回0;
}
除非A被终止,否则B无法读取内容

这是因为A实际上并没有写东西
stdio
流(由
FILE*
表示)被缓冲。您可以使用设置缓冲模式。默认情况下,使用
fdopen()
在管道上打开的流将被完全缓冲,因此在缓冲区已满之前,不会发生对管道的实际写入

最简单的解决方案是在代码中希望写入的任何位置调用,例如直接在
fprintf()
之后的代码中:

除非A被终止,否则B无法读取内容

这是因为A实际上并没有写东西
stdio
流(由
FILE*
表示)被缓冲。您可以使用设置缓冲模式。默认情况下,使用
fdopen()
在管道上打开的流将被完全缓冲,因此在缓冲区已满之前,不会发生对管道的实际写入

最简单的解决方案是在代码中希望写入的任何位置调用,例如直接在
fprintf()
之后的代码中:


首先,代码中有许多不必要的行。您可以直接使用read()和write()系统调用,而不是执行fdopen()。其次,fork()系统调用将0返回给子进程,将子进程的pid返回给父进程。最后,家长应该等待孩子完成并从内存中清除它,以阻止它变成僵尸

这是您的代码的正确版本,可以完美地工作而不中断

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

int main()
{
   int status;   // To get return status of file
   // No need of FILE pointer
   int mypipe[2];  // No need to make it global
   pid_t pid = 0;
   int num = 0, temp;

   pipe(mypipe); // Create pipe

   if((pid = fork()) == 0)   // Child block
   {
      close(mypipe[1]);   // Child will close the writing end

      while (1)
      {
          read(mypipe[0],&temp,sizeof(int));
          printf("from child: %d\n",temp);
      }
      exit(0);  // Exit the child
   }
   else     // Parent block
   {
      close(mypipe[0]);   // Parent will close the reading end of pipe
      while (1)
      {
          scanf("%d", &num);
          write(mypipe[1],&num,sizeof(int));
      }
   }

   // Parent should wait for child
   wait(&status);
   return 0;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
int status;//获取文件的返回状态
//不需要文件指针
int mypipe[2];//无需将其设置为全局
pid_t pid=0;
int num=0,温度;
管道(mypipe);//创建管道
if((pid=fork())==0)//子块
{
close(mypipe[1]);//子进程将关闭写入端
而(1)
{
读取(mypipe[0],&temp,sizeof(int));
printf(“来自子项:%d\n”,temp);
}
退出(0);//退出子级
}
else//父块
{
关闭(mypipe[0]);//父级将关闭管道的读取端
而(1)
{
scanf(“%d”和&num);
写入(mypipe[1],&num,sizeof(int));
}
}
//父母应该等孩子
等待(&状态);
返回0;
}
阅读系统调用手册页
man 2读取、man 2写入等。

首先,代码中有许多不必要的行。您可以直接使用read()和write()系统调用,而不是执行fdopen()。其次,fork()系统调用将0返回给子进程,将子进程的pid返回给父进程。最后,家长应该等待孩子完成并从内存中清除它,以阻止它变成僵尸

这是您的代码的正确版本,可以完美地工作而不中断

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

int main()
{
   int status;   // To get return status of file
   // No need of FILE pointer
   int mypipe[2];  // No need to make it global
   pid_t pid = 0;
   int num = 0, temp;

   pipe(mypipe); // Create pipe

   if((pid = fork()) == 0)   // Child block
   {
      close(mypipe[1]);   // Child will close the writing end

      while (1)
      {
          read(mypipe[0],&temp,sizeof(int));
          printf("from child: %d\n",temp);
      }
      exit(0);  // Exit the child
   }
   else     // Parent block
   {
      close(mypipe[0]);   // Parent will close the reading end of pipe
      while (1)
      {
          scanf("%d", &num);
          write(mypipe[1],&num,sizeof(int));
      }
   }

   // Parent should wait for child
   wait(&status);
   return 0;
}
#包括
#包括
#包括
#包括
#包括
int main()
{
int status;//获取文件的返回状态
//不需要文件指针
int mypipe[2];//无需将其设置为全局
pid_t pid=0;
int num=0,温度;
管道(mypipe);//创建管道
if((pid=fork())==0)//子块
{
close(mypipe[1]);//子进程将关闭写入端
而(1)
{
读取(mypipe[0],&temp,sizeof(int));
printf(“来自子项:%d\n”,temp);
}
退出(0);//退出子级
}
else//父块
{
关闭(mypipe[0]);//父级将关闭管道的读取端
而(1)
{
scanf(“%d”和&num);
写入(mypipe[1],&num,sizeof(int));
}
}
//父母应该等孩子
等待(&状态);
返回0;
}
阅读系统调用手册页
man 2读取、man 2写入等。

stdio
流(
文件*
)被缓冲。使用操作系统提供的原始读/写操作,或在每次写入后尝试
fflush()
stdio
流(
FILE*
)被缓冲。请使用操作系统提供的原始读/写操作,或在每次写入后尝试
fflush()
。非常感谢!你的回答对我帮助很大。非常感谢!您的回答对我帮助很大。“您可以直接使用read()和write()系统调用代替fdopen()。”您可以使用read()write()系统调用和sprintf()、sscanf()进行格式化。我认为不需要其他任何东西,这是不必要的复杂。如果需要格式化,只需使用标准的
文件*
流即可。此外,
read()
write()
(以及
fdopen()
)不是标准C,而是由POSIX系统提供的。使用它们是不可移植的,您可能需要为不同的系统使用不同的功能来替换它们。如果你对管道所做的一切都是
fdopen()
它的末端,那么剩下的代码都是标准的C,移植只意味着你必须替换给你
文件的代码*
。管道也是一个系统调用,它需要内核的帮助来完成这项工作。因此,如果您使用的是pipe(),那么使用read()write()应该不会有问题,因为在内部printf()文件I/O也会做同样的事情