你的代码是一个示例程序,展示了父进程和子进程如何通过信号量进行同步,以读取和写入文件。下面是对这段代码的格式化、注释以及一些注意事项的说明:
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <string.h>
#include "sem_pv.h" // 包含你之前定义的信号量操作函数
int main(void) {
key_t key;
int pid, fd, semid, n;
char str[80];
// 生成唯一的键值
key = ftok(".", 5);
// 初始化信号量
semid = sem_init(key);
// 打开或创建测试文件
fd = open("test.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
// 创建子进程
while ((pid = fork()) == -1);
if (pid == 0) { // 子进程
sleep(1); // 确保父进程先执行
sem_p(semid); // P操作,获取信号量
lseek(fd, SEEK_SET, 0); // 将文件指针移动到开头
read(fd, str, sizeof(str)); // 从文件中读取数据
sem_v(semid); // V操作,释放信号量
printf("child: read str from test file: %s\n", str);
exit(0);
} else { // 父进程
sem_p(semid); // P操作,获取信号量
printf("parent: please enter a string for the test file (strlen<80):\n");
fgets(str, sizeof(str), stdin); // 使用fgets替代gets以避免缓冲区溢出问题
n = strlen(str);
lseek(fd, SEEK_SET, 0); // 将文件指针移动到开头
write(fd, str, n); // 向文件写入数据
sem_v(semid); // V操作,释放信号量
wait(0); // 等待子进程结束
close(fd); // 关闭文件描述符
sem_rmv(semid); // 删除信号量
exit(0);
}
}
注意事项:
输入安全:使用
fgets
替代gets
是更安全的做法,因为gets
不会检查缓冲区大小,容易导致缓冲区溢出。错误处理:建议在打开文件、初始化信号量、读写等地方加入错误处理机制,以便于调试和确保程序的健壮性。
清理资源:确保每次运行程序后能正确删除或清理所有资源,包括打开的文件和创建的信号量。
并发控制:本例中的信号量主要用于保证在父进程向文件写入内容时,子进程不能同时读取,这样可以防止竞争条件。
内容由零声教学AI助手提供,问题来源于学员提问