我实现了一个涉及子进程和父进程之间双向通信的场景。子进程使用execvp启动另一个c程序(比如XYZ)。 Parent在pipe1的一端写入数据,pipe1的另一端复制到child的stdin。所以孩子读取这些数据,执行一些操作并将数据写回stdout。这个stdout被复制以写入pipe2的结尾,现在父读取来自pipe2的读取端。不修改外部程序XYZ。要遵循的顺序是
1)parent将数据写入pipe1 2)子进程从pipe1的重复结束(stdin)读取数据 3)child对数据进行一些修改并将数据写回stdout,stdout被复制到读取pipe2的末尾 4)父尝试从pipe2的读取端读取数据。
上述情况可以重复多次。
以上场景的示例以及示例 1)父母写1 2)子读取1并进行修改并将1(修改后)写入stdout 3)现在父母读取这些数据并打印回来 4)打印后,父对象2写入stdin 5)继续如上.....
我面临的问题是父母无法从pipe2的读取端读取数据。它实际上是在闲逛。
Imp注意:我还没有关闭pipe1的写句柄,因为我需要再次写入数据。如果我关闭手柄,我无法重新打开它,因为管道不支持它。
代码如下所示
void Child_write (pid_t Handle);
void Parent_write (pid_t Handle, char c);
void Child_read (pid_t Handle);
void Parent_read (pid_t Handle);
void main()
{
pid_t Pid;
int writepipe[2],readpipe [2];
pipe(readpipe); /* Create two file descriptors */
pipe(writepipe); /* Create two file descriptors */
Pid = fork();
if (Pid == 0)
{
close(writepipe[1]); /* closing writepipe's write end */
dup2(writepipe[0],0); close(writepipe[0]); /* duplicating writepipe's read end to stdin*/
close(readpipe[0]); /* closing readpipe's read end*/
dup2(readpipe[1],1); close(readpipe[1]); /* duplicating readpipe's write end to stdout*/
Child_read(writepipe[0]); /* reading data from write pipe read end and then duplicating*/
}
else
{
close(writepipe[0]); /* closing writepipe's read end */
Parent_write(writepipe[1],'1'); /* pupming data to the writepipe */
close(readpipe[1]); /* closing the readpipes write end */
Parent_read(readpipe[0]); /* reading the data which is pumped into readpipe */
//Parent_write(writepipe[1],'2'); /* pupming data to the writepipe */
//Parent_read(readpipe[0]);
//Parent_write(writepipe[1],'3');
//Parent_read(readpipe[0]);
puts("***** End of parent process*****");
}
}
void Child_read(pid_t handle)
{
static char* command = "./stdoutput";
execvp(command, NULL);
}
void Parent_write(pid_t handle, char c)
{
char Buff[] = {'\n','\n'};
Buff[0] = c;
int n_written= write(handle, Buff, strlen(Buff)+1);
printf("write function has written %d no of bytes and the data written is %s",n_written,Buff);
//close(handle);
}
void Parent_read(pid_t handle)
{
printf("PARENT PROCESS: In Parent_read function\n");
int i=0;
int bytes_read = 0;
char buffer[1024]= {'\0'};
while (read(handle, buffer, sizeof(buffer)) > 0)
{
printf("PARENT PROCESS:: In while loop\n");
printf("The character/string read from readend of readpipe (stdout) is %s",buffer);
}
close(handle);
}
外部程序如下所示
void printing()
{
int c;
do
{
c = getchar();
printf("%c",c);
} while ((c != EOF) && (c != '\n'));
}
void main()
{
printing();
printing();
}
请帮帮我!!!!!!!!!
答案 0 :(得分:1)
在给定FILE *的第一次I / O调用(使用文件流函数)时,库决定流应该是行缓冲,块缓冲还是非缓冲。在你的情况下,当stdoutput启动时,它的stdoutput不是终端,所以流进入块缓冲模式,你的printf以缓冲区结束。
将您的主要功能更改为:
void main()
{
setvbuf(stdout, NULL, _IONBF, 0);
printing();
printing();
}
你的printf调用会产生写入。
您还应该查看setvbuf手册页,并学会使用strace:
strace -ff -o test.log ./myprog
会产生两个日志文件(一个用于父项,一个用于孩子),可以让你看到什么 系统调用由每个程序进行。
答案 1 :(得分:-1)