【发布时间】:2015-06-30 04:45:30
【问题描述】:
最后在这里查看并提出问题后,我能够编写这段代码,它生成 4 个子进程并通过 4 个不同的管道进行通信。 4 个子进程中的每一个都写入单个管道 (fd_log),但是当父进程从管道中读取时,它只读取来自进程 A 的第一条消息,来自进程 C 的第一条消息,来自进程的所有消息进程B 没有来自进程D。这是代码:
int main(int argc, char *argv[]) {
printf("\nWritten by Nawar Youssef\n");
int i, x=0, fd_log[2], fd_A_B[2], fd_B_C[2], fd_B_D[2], pipe_size=500;
char ch, msg_from_A[pipe_size], msg_to_B[pipe_size], msg_to_log[pipe_size],
msg_to_C[pipe_size], msg_to_D[pipe_size], msg_B_C[pipe_size], msg_B_D[pipe_size],
msg_from_log[pipe_size], temp_char[pipe_size], msg_C_log[pipe_size], msg_D_log[pipe_size];
pipe(fd_log);
pipe(fd_A_B);
pipe(fd_B_C);
pipe(fd_B_D);
if (fork()==0) { //child A
for (i=0; i < 10; i++) {
x = (rand() % 2);
if (x == 1)
ch='C';
else
ch='D';
//write records to A-B pipe
close(fd_A_B[READ]);
sprintf(msg_to_B, "%c %d", ch, i);
write(fd_A_B[WRITE], msg_to_B, strlen(msg_to_B)+1);
//write records to log pipe
close(fd_log[READ]);
sprintf(msg_to_log, "A sent to B: %c %d", ch, i);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
}//for
close(fd_A_B[WRITE]);
close(fd_log[WRITE]);
_exit(1);
}//if
if (fork()==0) { //child B
//read A-B pipe
close(fd_A_B[WRITE]);
int n_bytes = read(fd_A_B[READ], msg_from_A, sizeof(msg_from_A));
for(i=0; i < pipe_size; i++) {
if ( msg_from_A[i] == 'C') {
//write the message from B to C pipe
sprintf(msg_to_C, "%c %c", msg_from_A[i], msg_from_A[i+2]);
//printf("--%s\n", msg_to_C);
close(fd_B_C[READ]);
write(fd_B_C[WRITE], msg_to_C, strlen(msg_to_C)+1);
//write C message to log pipe
close(fd_log[READ]);
sprintf(msg_to_log, "B sent to C: %s", msg_to_C);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
sleep(1);
}else if (msg_from_A[i] == 'D') {
//write the message from B to D pipes
sprintf(msg_to_D, "%c %c", msg_from_A[i], msg_from_A[i+2]);
//printf("--%s\n", msg_to_D);
close(fd_B_D[READ]);
write(fd_B_D[WRITE], msg_to_D, strlen(msg_to_D)+1);
//write D message to log pipe
close(fd_log[READ]);
sprintf(msg_to_log, "B sent to D: %s", msg_to_D);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
sleep(5);
}else
continue;
}//for
close(fd_B_C[WRITE]); close(fd_B_D[WRITE]); close(fd_log[WRITE]);
_exit(1); //process B
}//if
if (fork()==0) { //child C
//read from B-C pipe
close(fd_B_C[WRITE]);
int n_bytes = read(fd_B_C[READ], msg_B_C, sizeof(msg_B_C));
for (i=0; i < pipe_size; i++) {
//write to log pipe
if (msg_B_C[i] == 'C') {
sprintf(msg_C_log, "%c %c", msg_B_C[i], msg_B_C[i+2]);
close(fd_log[READ]);
sprintf(msg_to_log, "C sent to log: %s", msg_C_log);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
}else
continue;
}
_exit(1); //process C
}
if (fork()==0) { //child D
//read from fd_B_D
close(fd_B_D[WRITE]);
int n_bytes = read(fd_B_D[READ], msg_B_D, sizeof(msg_B_D));
for (i=0; i < pipe_size; i++) {
//write to log pipe
if (msg_B_D[i] == 'D') {
sprintf(msg_D_log, "%c %c", msg_B_D[i], msg_B_C[i+2]);
close(fd_log[READ]);
sprintf(msg_to_log, "D sent to log: %s", msg_D_log);
write(fd_log[WRITE], msg_to_log, strlen(msg_to_log)+1);
}
}
_exit(1);
}//if
//parent
close(fd_log[WRITE]);
int n_bytes;
while( (n_bytes = read(fd_log[READ], msg_from_log, sizeof(msg_from_log)-1)) > 0){
printf("Log pipe reads (%d) bytes: %s\n", n_bytes, msg_from_log);
sleep(1);
}
close(fd_log[READ]);
return (0);
}
当我查看输出时,我知道所有消息都已读取(在输出中查看返回的字节数 read)。所以看起来问题在于显示消息。我用更简单的代码遇到了类似的问题,我通过使pipe_size 更大来解决它。但在这里它不起作用。
这是(#)之间的输出数是每次while循环读取的字节数:
由纳瓦尔·优素福撰写
日志管道读取 (187) 个字节:A 发送到 B:C 0
日志管道读取 (36) 字节:C 发送到日志:C 0
日志管道读取 (17) 个字节:B 发送到 C:C 2
日志管道读取 (35) 个字节:B 发送到 D:D 3
日志管道读取 (17) 个字节:B 发送到 D:D 4
日志管道读取 (17) 个字节:B 发送到 D:D 5
日志管道读取 (17) 个字节:B 发送到 D:D 6
日志管道读取 (17) 个字节:B 发送到 D:D 7
日志管道读取 (17) 个字节:B 发送到 C:C 8
日志管道读取 (17) 个字节:B 发送到 C:C 9
【问题讨论】:
标签: c process pipe parent-child