编辑:
解决方案为: int c1=dup2(pipes[0][1],STDOUT_FILENO);
int c2=dup2(pipes[1][0],STDIN_FILENO);
setvbuf(stdout,NULL,_IONBF,0);
使用SETVBUF设置stdout为非缓冲区。即使我打印了换行符,如果目标不是实际屏幕,我猜它会成为缓冲区。
编辑: 当我在LINE 1之后放置fflush(stdout),并在LINE 4之后放置fflush(fout)时,它按预期工作。但是,如果没有在LINE 1之后放置fflush(stdout),则无法正常工作。问题在于我无法在我计划运行的程序中放置fflush。
我正在尝试从我的进程启动另一个程序。我无法访问其代码,但我知道它使用stdin和stdout进行用户交互。我正在尝试通过创建2个管道,fork-ing并将子进程的stdin / stdout重定向到正确的管道端来启动该程序。关键是父进程应该能够通过文件描述符与子进程通信,而其stdin / stdout应保持不变。 POPEN系统调用仅打开单向管道。以下代码几乎有效。
有4行标记为LINE 1..4。
LINE 1是子进程发送到管道, LINE 2是子进程从管道接收, LINE 3是父进程发送到管道, LINE 4是父进程从管道接收,
这只是一个玩具示例,以确保一切正常。问题在于如果取消注释所有4个行LINE1..4,则在终端上看到的输出为
PARENT1: -1
FD: 1 0 4 5 0 1
DEBUG1: 0
DEBUG2: 0
如果只取消注释LINE 1和LINE 3,则只会看到连续的数据流。如果只取消注释LINE 2和LINE 4,则也会发生同样的情况。然而,我想要完全的双向通信。添加已注释的SLEEP也不会改变行为。
问题可能是什么?我想知道为什么没有双向POPN。
int pid;
int pipes[2][2];
pipe(pipes[0]);
pipe(pipes[1]);
pid=fork();
if(pid==0)
{
//usleep(1000000);
close(pipes[0][0]);
close(pipes[1][1]);
int c1=dup2(pipes[0][1],STDOUT_FILENO);
int c2=dup2(pipes[1][0],STDIN_FILENO);
//int c2=dup2(STDIN_FILENO,pipes[1][0]);
fprintf(stderr,"FD: %d %d %d %d %d %d\n",c1,c2,pipes[0][1],pipes[1][0],STDIN_FILENO,STDOUT_FILENO);
//FILE*fout=fdopen(pipes[0][1],"w");
//FILE*fin =fdopen(pipes[1][0],"r");
while(1)
{
static int c1=0;
fprintf(stderr,"DEBUG1: %d\n",c1);
printf("%d\n",c1); // LINE 1
fprintf(stderr,"DEBUG2: %d\n",c1);
scanf("%d",&c1); // LINE 2
fprintf(stderr,"DEBUG3: %d\n",c1);
c1++;
}
//fclose(fout);
//fclose(fin);
return 0;
}
close(pipes[0][1]);
close(pipes[1][0]);
char buffer[100];
FILE*fin=fdopen(pipes[0][0],"r");
FILE*fout=fdopen(pipes[1][1],"w");
while(1)
{
int c1=-1;
printf("PARENT1: %d\n",c1);
fscanf(fin,"%d",&c1); // LINE 3
printf("Recv: %d\n",c1);
fprintf(fout,"%d\n",c1+1); // LINE 4
printf("PARENT3: %d\n",c1+1);
}
fclose(fin);
fclose(fout);