我正在尝试使用fork()通过两个进程从文件开头读取数据的示例程序。
调用fork()时,内核会创建子进程,并且此子进程会继承父进程的属性。所有打开的文件和文件描述符。我的目标是从孩子和父母一起从头开始阅读文件。 我尝试使用dup2()创建单独的描述符,但它不起作用。
我的第二个问题是,有没有办法让子进程在完成初始任务后继续处理另一个任务。 (必须将信号发送给父母以询问另一项任务?父母将通过管道或者fifo与孩子沟通)
int main(int argc, char* argv[]){
int fd1,fd2;
int fd;
int read_bytes;
pid_t pid;
char* buff;
buff = malloc(sizeof(buff)*5);
if(argc < 2){
perror("\nargc: Forgot ip file");
return 1;
}
fd = open(argv[1],O_RDONLY);
if(-1 == fd){
perror("\nfd: ");
return 2;
}
pid = fork();
if(pid == -1){
perror("\n pid");
return 1;
}
else if(pid == 0){ // CHILD
dup2(fd1,fd);
read_bytes = read(fd1,buff,5);
printf("\n %s \n",buff);
}
else{ //PARENT
wait();
printf("\n Parent \n");
dup2(fd2,fd);
//close(fd);
read_bytes = read(fd2,buff,5);
printf("\n %s \n",buff);
}
return 0;
}
请帮助理解
答案 0 :(得分:2)
(1)正如loreb在评论中提到的那样,dup2
重复文件描述符。来自man (2) dup2
:
在从这些系统调用之一成功返回之后,旧文件描述符和新文件描述符可以互换使用。它们引用相同的打开文件描述(参见open(2)),从而共享文件偏移量和文件状态标志;例如,如果通过在其中一个描述符上使用lseek(2)修改文件偏移量,则另一个描述符的偏移量也会更改。
所以你得到了一个糟糕的假设。只需关闭并在孩子中第二次打开文件。
(2)dup2签名是int dup2(int oldfd, int newfd)
。你正在做dup2(fd1, fd)
,但是fd是你要复制的描述符,所以你可以反转parms。
(3)局部变量没有初始化,所以
int fd1,fd2;
有随机值。当你执行dup2(fd1, fd)
时,你试图使用fd1中的任何随机值,如果它是任何(通常)大于1023将导致调用因EBADF而失败。
(4)wait()
接受一个参数,因此它至少应为wait(NULL)
。
(5)始终检查系统调用的返回值。您的dup
,read
等几乎肯定会失败。
我建议将其投入使用,然后将您的第二个问题作为单独的帖子提交。