【发布时间】:2015-03-05 04:07:29
【问题描述】:
我正在尝试用 c 语言编写一个程序,它分叉一个孩子,并使用两个单独的管道进行双向通信。
总结;
- 父亲写入 pipe1
- 孩子从 pipe1 中读取数据并进行计算
- 孩子将答案写在 pipe2 中
- 父亲从pipe2中读取信息
在第 3 步之前一切顺利,如果我从第 4 点注释代码,那么一切正常,我什至检查对 pipe2 的写入,它似乎工作,但是当我尝试从父亲的 pipe2 中读取代码它挂起,甚至不执行子计算,第 2 步和第 3 步。请帮助我。这是我目前的代码。
int main(int argc, char *argv[]) {
pid_t pid;
pid_t* trabajadores;
int nHijos = 1;
trabajadores = (pid_t*)malloc(sizeof(pid_t) * nHijos);
int** aHijos;
int links = 0;
// Matriz de pipes
aHijos = (int **) malloc(sizeof(int *) * nHijos);
for (i = 0; i < nHijos; i++) {
aHijos[i] = (int *) malloc(sizeof(int)*2);
}
int alPadre[2];
pipe(alPadre);
// Se crea el pool de procesos
for (i = 0; i < nHijos; i++) {
pipe(aHijos[i]);
pid = fork();
if (pid == 0) {
int j;
FILE* salidaHijo;
FILE* entradaHijo;
char buffer2[1024];
close(alPadre [0]);
for (j = 0; j<i; j++) {
close(aHijos[j][0]);
close(aHijos[j][1]);
}
close(aHijos[i][1]);
entradaHijo = fdopen(aHijos[i][0], "r");
// STEP 2
while ( !feof (entradaHijo) && fgets (buffer2, sizeof (buffer2), entradaHijo) != NULL) {
buffer2[strcspn(buffer2, "\n")] = 0;
}
char* resultado;
/* CALCULATIONS */
// STEP 3
salidaHijo = fdopen(alPadre[1], "w");
printf("%i\n", fprintf(salidaHijo, "%s\n", resultado));
fflush (salidaHijo);
exit(0);
} else {
trabajadores[i] = 0;
close(alPadre[1]);
close(aHijos[i][0]);
// STEP 1
FILE** salidaPadre;
salidaPadre = (FILE**)malloc(sizeof(FILE*) * nHijos);
for (i = 0; i < nHijos; i++) {
salidaPadre[i] = fdopen(aHijos[i][1], "w");
}
fprintf(salidaPadre[j], "%s\n", DesencolarT(trabajos));
trabajadores[j] = 1;
sleep(5);
// STEP 4
char buffer[1024];
entradaPadre = fdopen(alPadre[0], "r");
read(alPadre[0], buffer, sizeof(buffer));
while ( !feof (entradaPadre) && fgets (buffer, sizeof (buffer), entradaPadre) != NULL) {
printf("%s\n", buffer);
}
}
}
return 0;
}
不会编译它只是我代码的粘贴部分,这是两个进程的 strace -ff -o test.log ./myProg 的输出。
getdents(4, /* 0 entries */, 32768) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7761000
write(1, ". 160\n", 6) = 6
fcntl64(6, F_GETFL) = 0x1 (flags O_WRONLY)
fstat64(6, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7760000
_llseek(6, 0, 0xbfb8895c, SEEK_CUR) = -1 ESPIPE (Illegal seek)
read(3, 0xbfb89738, 1024) = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---
+++ killed by SIGINT +++
与
close(3) = 0
close(6) = 0
fcntl64(5, F_GETFL) = 0 (flags O_RDONLY)
fstat64(5, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7761000
_llseek(5, 0, 0xbfb8895c, SEEK_CUR) = -1 ESPIPE (Illegal seek)
read(5, 0xb7761000, 4096) = ? ERESTARTSYS (To be restarted)
--- SIGINT (Interrupt) @ 0 (0) ---
谢谢你,很抱歉西班牙语的长篇和可怕的格式。
在第 1 步和第 3 步之后使用 fflush(),如果我在第 1 步之后关闭 pipe1() 一切正常,问题是我需要在未来继续写信给那个孩子,所以我可以'关闭它。
【问题讨论】:
-
发布的代码无法编译,是不是缺少某些部分? (如果人们可以编译发布的代码以查看它如何工作/不适合他们,您将获得更好的帮助)
-
pipe在标准 C99 或 C11 中不存在。这是一个 POSIX 或 Linux 调用。所以你应该用 POSIX 或 Linux 标记你的问题。