使用unix管道时遇到了一个奇怪的错误。我写了一个简短的程序来展示这个问题。
以下是代码:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char*args[]){
int fd[2];
pipe(fd);
int pid = fork();
if(pid<0){
perror("fork()");
exit(1);
}else if(pid == 0){
close(fd[0]);
const char* msg = "I'm here\n";
size_t len = strlen(msg) + 1; // +1 for null char
write(fd[1], msg, len);
while(1){/*does other work*/}
}else{
close(fd[1]);
}
pid = fork();
if(pid<0){
perror("fork()");
exit(1);
}else if(pid == 0){
close(fd[0]);
const char* msg = "I'm here\n";
size_t len = strlen(msg) + 1; // +1 for null char
write(fd[1], msg, len);
while(1){/*does other work*/}
}else{
close(fd[1]);
}
//close(fd[1]);
sleep(5);
const char* msg = "I'm here\n";
size_t len = strlen(msg) + 1; // +1 for null char
char str[len];
fcntl(fd[0],F_SETFL, O_NONBLOCK);
if(read(fd[0], str, len)<=0){
printf("Nothing from child\n");
}
/*does other work*/
fcntl(fd[0],F_SETFL, O_NONBLOCK);
if(read(fd[0], str, len)<=0){
printf("Nothing from child\n");
}
printf("finished read\n");
/*does other work*/
wait(NULL);
return 0;
}
父进程分叉两个子节点并创建一个管道。两个子进程写入管道,父管道从管道读取。
父进程应该恢复子进程写的所有信息。
但是,当我运行上述程序时,父打印出来
Nothing from child
finished read
为什么?
有趣的是,如果我写一个关闭(fd [1]),就像这样:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char*args[]){
int fd[2];
pipe(fd);
int pid = fork();
if(pid<0){
perror("fork()");
exit(1);
}else if(pid == 0){
close(fd[0]);
const char* msg = "I'm here\n";
size_t len = strlen(msg) + 1; // +1 for null char
write(fd[1], msg, len);
while(1){/*does other work*/}
}else{
}
pid = fork();
if(pid<0){
perror("fork()");
exit(1);
}else if(pid == 0){
close(fd[0]);
const char* msg = "I'm here\n";
size_t len = strlen(msg) + 1; // +1 for null char
write(fd[1], msg, len);
while(1){/*does other work*/}
}else{
}
close(fd[1]);//HERE IS THE DIFFERENCE
sleep(5);
const char* msg = "I'm here\n";
size_t len = strlen(msg) + 1; // +1 for null char
char str[len];
fcntl(fd[0],F_SETFL, O_NONBLOCK);
if(read(fd[0], str, len)<=0){
printf("Nothing from child\n");
}
/*does other work*/
fcntl(fd[0],F_SETFL, O_NONBLOCK);
if(read(fd[0], str, len)<=0){
printf("Nothing from child\n");
}
printf("finished read\n");
/*does other work*/
wait(NULL);
return 0;
}
它有效,如果我根本不接近(fd [1])也可以。我迷路了,为什么close()的位置会影响管道的读数?
答案 0 :(得分:1)
我不确定这是不是你的问题,但这句话显然是错误的:
write(fd[1], "I'm here\n", 256);
您正在从源缓冲区写入256个字节,这是一个非常短的静态字符串。我想你想这样说:
const char* msg = "I'm here\n";
size_t len = strlen(msg); // could be strlen(msg)+1 - see discussion in comments.
write(fd[1], "I'm here\n", len);