在协同进程中读取后子进程挂起
Posted
技术标签:
【中文标题】在协同进程中读取后子进程挂起【英文标题】:child process pending after read in coprocess 【发布时间】:2012-06-22 03:37:03 【问题描述】:我正在使用管道编写一个协同处理程序。当孩子读取一些数据,处理并输出它时,它工作正常。但是当我读取所有数据并处理它时,它只是挂起。任何机构有一些想法?谢谢。
这里是源代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
int main()
#define MAXSIZE 1024
char workload[MAXSIZE];
char result[MAXSIZE];
workload[strlen(workload)] = EOF;
int workload_size = strlen(workload);
int fd1[2], fd2[2];
int n;
pid_t pid;
if (pipe(fd1) < 0 || pipe(fd2) < 0)
fprintf(stderr, "pipe error: %s\n", strerror(errno));
exit(1);
if ((pid = fork()) < 0)
fprintf(stderr, "fork error: %s\n", strerror(errno));
exit(1);
else if (pid > 0)
close(fd1[0]);
close(fd2[1]);
while(fgets(workload, MAXSIZE, stdin) != NULL)
workload_size = strlen(workload);
if (write(fd1[1], workload, workload_size) != workload_size)
fprintf(stderr, "write to pipe error: %s\n", strerror(errno));
exit(1);
if ((n = read(fd2[0], result, MAXSIZE)) < 0)
fprintf(stderr, "read from pipe error: %s\n", strerror(errno));
exit(1);
if (n == 0)
fprintf(stderr, "child closed the pipe\n");
exit(1);
result[n] = 0;
if (puts(result) == EOF)
fprintf(stderr, "fputs error\n");
exit(1);
else
close(fd1[1]);
close(fd2[0]);
if (fd1[0] != STDIN_FILENO)
if (dup2(fd1[0] ,STDIN_FILENO) != STDIN_FILENO)
fprintf(stderr, "dup2 error to stdin.\n");
exit(1);
close(fd1[0]);
if (fd2[1] != STDOUT_FILENO)
if (dup2(fd2[1] ,STDOUT_FILENO) != STDOUT_FILENO)
fprintf(stderr, "dup2 error to stdout.\n");
exit(1);
close(fd2[1]);
if (execl("./a.out", "a.out", NULL) < 0)
fprintf(stderr, "execl error: %s\n", strerror(errno));
exit(1);
exit(0);
return 0;
这里是 a.out 的源代码,它可以很好地配合这个:
#include <stdio.h>
#include <string.h>
int main()
#define MAXSIZE 1024
char x[MAXSIZE];
int n;
while(scanf("%s", x) != EOF)
printf("len:%d %s", strlen(x), x);
fflush(stdout);
return 0;
但是当我编写这样的代码时,它似乎只是悬而未决:
#include <stdio.h>
#include <string.h>
int main()
#define MAXSIZE 1024
char x[MAXSIZE];
int n;
while(scanf("%s", x) != EOF);
printf("Ok\n");
fflush(stdout);
return 0;
【问题讨论】:
【参考方案1】:您使用%s
调用scanf
的方式可能会溢出x
缓冲区。您至少应该使用宽度修饰符修改 scanf。
#include <stdio.h>
#include <string.h>
int main()
#define MAXSIZE 1024
char x[MAXSIZE];
int n;
while(scanf("%1024s", x) != EOF)
printf("len:%d %s", strlen(x), x);
fflush(stdout);
return 0;
对于您的其他程序也是如此。
您的程序被阻止的原因是因为您的第二个a.out
程序循环执行另一个scanf
,同时父程序正试图将响应读回result
。
【讨论】:
谢谢。在将必要的数据写入子进程后,我通过关闭管道解决了这个问题。【参考方案2】:你应该测试和循环而不是feof,你可以使用popen & pclose
您可能想使用一些多路复用系统调用,例如poll
【讨论】:
以上是关于在协同进程中读取后子进程挂起的主要内容,如果未能解决你的问题,请参考以下文章