面试题答案
一键面试- 子进程对父进程打开文件描述符的生命周期影响
- 子进程会继承父进程的文件描述符表。这意味着父进程打开的所有文件描述符在子进程中同样有效,并且指向相同的打开文件对象。例如,如果父进程打开了一个文件,子进程可以使用相同的文件描述符继续对该文件进行读写操作。
- 父进程和子进程对文件描述符的操作是共享文件偏移量的。例如,父进程读取了一定字节的数据,文件偏移量会相应移动,子进程接着读取数据时,会从父进程移动后的偏移量位置开始读取。
- 保证父子进程对文件描述符正确操作和资源释放的方法
- 操作方面:父子进程在操作文件描述符时要注意同步问题。如果父子进程同时对同一个文件描述符进行写操作,可能会导致数据混乱。可以通过加锁机制(如使用文件锁)来保证同一时间只有一个进程对文件进行写操作。
- 资源释放方面:在父子进程结束时,都要确保关闭不再使用的文件描述符。在
fork
之后,父子进程可以根据自身逻辑判断是否需要继续使用文件描述符,如果不需要则调用close
函数关闭。
- 代码示例
#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
函数关闭文件描述符,以确保资源的正确释放。同时,这里简单的先后写入操作避免了同步问题,如果有更复杂的读写场景,需要引入文件锁等机制来保证数据一致性。