0

我正在尝试一个示例程序,通过使用 fork() 的两个进程从文件开头读取数据。

当调用 fork() 时,内核会创建一个子进程,这个子进程继承父进程的属性。所有打开的文件和文件描述符。我的目标是让孩子和父母从头开始阅读文件。我尝试使用 dup2() 创建单独的描述符,但它不起作用。

我的第二个问题是,有没有办法让子进程在完成初始任务后继续处理另一个任务。(信号必须发送给父母以要求另一项任务?父母将通过管道或先进先出与孩子沟通)

 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;
}

请帮忙理解

4

1 回答 1

2

(1) 正如评论中提到的 loreb,dup2 复制文件描述符。智慧man (2) dup2

从这些系统调用之一成功返回后,新旧文件描述符可以互换使用。它们引用相同的打开文件描述(参见 open(2)),因此共享文件偏移量和文件状态标志;例如,如果在其中一个描述符上使用 lseek(2) 修改了文件偏移量,则另一个描述符的偏移量也会改变。

所以你得出了一个错误的假设。只需在孩子中第二次关闭并打开文件。

(2) dup2 签名是int dup2(int oldfd, int newfd). 您正在这样做dup2(fd1, fd),但 fd 是您要复制的描述符,因此您可以反转参数。

(3) 局部变量没有被初始化所以

int fd1,fd2;

有随机值。当您dup2(fd1, fd)尝试使用 fd1 中的任何随机值时,如果它(通常)大于 1023 将导致调用因 EBADF 失败。

(4)wait()接受一个参数,所以它至少应该是wait(NULL).

(5)始终检查系统调用的返回值。您dup的 s、reads 等几乎肯定会失败。

我建议让它发挥作用,然后将您的第二个问题作为单独的帖子提交。

于 2013-09-03T21:25:42.980 回答