我正在尝试一个示例程序,通过两个进程使用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;
}
请帮助理解
(1)正如loreb在注释中提到的,dup2
复制文件描述符。即来自man (2) dup2
:
在这些系统调用中的一个成功返回之后,旧的和新的文件描述符可以互换使用。它们引用相同的打开文件描述(参见打开(2)),因此共享文件偏移量和文件状态标志;例如,如果通过在其中一个描述符上使用lseek(2)来修改文件偏移量,那么另一个描述符的偏移量也会发生变化。
所以你做了一个错误的假设。只需在子级中第二次关闭并打开文件。
(2) dup2签名是CCD_ 3。您正在执行dup2(fd1, fd)
,但是fd是您想要复制的描述符,因此您可以反转parms。
(3) 本地变量未初始化,因此
int fd1,fd2;
具有随机值。当你执行dup2(fd1, fd)
时,你试图使用fd1中的任何随机值,如果它(通常)大于1023,就会导致EBADF调用失败。
(4) wait()
取一个参数,所以它至少应该是wait(NULL)
。
(5) 总是检查系统调用的返回值。你的dup
、read
等等,几乎肯定会失败。
我建议你把这件事做好,然后把你的第二个问题作为一个单独的帖子提交。