面试题答案
一键面试可能出现的资源竞争问题
当多个进程同时向同一个文件写入数据时,可能会导致数据错乱。例如,进程A写入一部分数据,进程B在A还未完全写完时也开始写入,这样会使文件中的数据顺序混乱,无法保证完整性。
解决方法 - 使用文件锁机制
可以使用fcntl
函数来实现文件锁。文件锁分为建议性锁和强制性锁,这里使用建议性锁(记录锁)。当一个进程对文件加锁后,其他进程尝试对同一区域加锁时会失败,从而避免资源竞争。
关键代码片段
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd == -1) {
perror("open");
return 1;
}
pid_t pid = fork();
if (pid == -1) {
perror("fork");
close(fd);
return 1;
} else if (pid == 0) { // 子进程
struct flock lock;
lock.l_type = F_WRLCK; // 写锁
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0; // 锁定整个文件
if (fcntl(fd, F_SETLKW, &lock) == -1) {
perror("fcntl lock");
close(fd);
return 1;
}
write(fd, "Child process writing\n", 20);
lock.l_type = F_UNLCK; // 解锁
if (fcntl(fd, F_SETLK, &lock) == -1) {
perror("fcntl unlock");
}
close(fd);
exit(0);
} else { // 父进程
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
if (fcntl(fd, F_SETLKW, &lock) == -1) {
perror("fcntl lock");
close(fd);
return 1;
}
write(fd, "Parent process writing\n", 21);
lock.l_type = F_UNLCK;
if (fcntl(fd, F_SETLK, &lock) == -1) {
perror("fcntl unlock");
}
close(fd);
wait(NULL);
}
return 0;
}