MST

星途 面试题库

面试题:C语言Linux文件描述符在多进程中的生命周期管理

在C语言的Linux编程中,当一个进程通过fork创建子进程后,子进程对父进程打开的文件描述符的生命周期管理会受到哪些影响?如何保证父子进程对文件描述符的正确操作和资源释放?请结合代码示例详细阐述。
47.9万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 子进程对父进程打开文件描述符的生命周期影响
    • 子进程会继承父进程的文件描述符表。这意味着父进程打开的所有文件描述符在子进程中同样有效,并且指向相同的打开文件对象。例如,如果父进程打开了一个文件,子进程可以使用相同的文件描述符继续对该文件进行读写操作。
    • 父进程和子进程对文件描述符的操作是共享文件偏移量的。例如,父进程读取了一定字节的数据,文件偏移量会相应移动,子进程接着读取数据时,会从父进程移动后的偏移量位置开始读取。
  2. 保证父子进程对文件描述符正确操作和资源释放的方法
    • 操作方面:父子进程在操作文件描述符时要注意同步问题。如果父子进程同时对同一个文件描述符进行写操作,可能会导致数据混乱。可以通过加锁机制(如使用文件锁)来保证同一时间只有一个进程对文件进行写操作。
    • 资源释放方面:在父子进程结束时,都要确保关闭不再使用的文件描述符。在fork之后,父子进程可以根据自身逻辑判断是否需要继续使用文件描述符,如果不需要则调用close函数关闭。
  3. 代码示例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#define BUFFER_SIZE 1024

int main() {
    // 打开一个文件
    int fd = open("test.txt", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        close(fd);
        return 1;
    } else if (pid == 0) {
        // 子进程
        const char* child_message = "This is from child process.\n";
        ssize_t write_bytes = write(fd, child_message, strlen(child_message));
        if (write_bytes == -1) {
            perror("child write");
        }
        close(fd); // 子进程使用完文件描述符后关闭
        exit(0);
    } else {
        // 父进程
        const char* parent_message = "This is from parent process.\n";
        ssize_t write_bytes = write(fd, parent_message, strlen(parent_message));
        if (write_bytes == -1) {
            perror("parent write");
        }
        wait(NULL); // 等待子进程结束
        close(fd); // 父进程使用完文件描述符后关闭
    }

    return 0;
}

在上述代码中,父进程先打开一个文件,然后fork出子进程。父子进程分别向文件中写入不同的信息。注意,父子进程在使用完文件描述符后都调用了close函数关闭文件描述符,以确保资源的正确释放。同时,这里简单的先后写入操作避免了同步问题,如果有更复杂的读写场景,需要引入文件锁等机制来保证数据一致性。