使用系统调用open read write,完成一个C语言程序:该程序接收两个参数,参数1作为要读写的文件,参数2作为标志位,标识是读还是写。功能完成对参数1所示文件的读写,该文件的内容为 “学号 MYFILE”,其中学号填为自己的学号。 2. 改造上面的程序,完成: i. 使用semaphore,并利用该程序生成2个进程,这两个进程写同一个文件,要求:a.互斥写,即只有一个进程写完后,才能让另一个进程写; b. 一个进程写入内容:“自己学号的后3位PROC1 MYFILE1”;另一个进程写入内容:“自己学号的后3位PROC2 MYFILE2 ii. 将上面程序的semaphore替换成strict alternation算法,完成上面两个进程的互斥。
时间: 2024-02-13 22:07:09 浏览: 86
下面是第一问的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s filename r/w\n", argv[0]);
exit(1);
}
// 打开文件
int fd = open(argv[1], O_RDWR);
if (fd == -1) {
perror("open");
exit(1);
}
// 读或写文件
if (argv[2][0] == 'r') {
char buf[100];
int n = read(fd, buf, 100);
if (n == -1) {
perror("read");
exit(1);
}
printf("Read from file: %s\n", buf);
} else if (argv[2][0] == 'w') {
char buf[100];
sprintf(buf, "学号 %s", "MYFILE");
int n = write(fd, buf, strlen(buf));
if (n == -1) {
perror("write");
exit(1);
}
printf("Write to file: %s\n", buf);
} else {
printf("Unknown command: %s\n", argv[2]);
exit(1);
}
// 关闭文件
if (close(fd) == -1) {
perror("close");
exit(1);
}
return 0;
}
```
下面是第二问的代码,使用 semaphore 实现互斥写:
```c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/wait.h>
#define SEM_NAME "/my_sem"
#define FILE_NAME "my_file.txt"
int main() {
// 初始化 semaphore
sem_t *sem = sem_open(SEM_NAME, O_CREAT | O_EXCL, 0666, 1);
if (sem == SEM_FAILED) {
perror("sem_open");
exit(1);
}
// 创建子进程
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
// 子进程
char buf[100];
sprintf(buf, "%sPROC1 %s", getenv("USER") + 4, FILE_NAME);
// 等待 semaphore
if (sem_wait(sem) == -1) {
perror("sem_wait");
exit(1);
}
// 写文件
int fd = open(FILE_NAME, O_WRONLY | O_APPEND);
if (fd == -1) {
perror("open");
exit(1);
}
int n = write(fd, buf, strlen(buf));
if (n == -1) {
perror("write");
exit(1);
}
printf("Child process write to file: %s\n", buf);
if (close(fd) == -1) {
perror("close");
exit(1);
}
// 释放 semaphore
if (sem_post(sem) == -1) {
perror("sem_post");
exit(1);
}
exit(0);
} else {
// 父进程
pid_t pid2 = fork();
if (pid2 == -1) {
perror("fork");
exit(1);
}
if (pid2 == 0) {
// 子进程
char buf[100];
sprintf(buf, "%sPROC2 %s", getenv("USER") + 4, FILE_NAME);
// 等待 semaphore
if (sem_wait(sem) == -1) {
perror("sem_wait");
exit(1);
}
// 写文件
int fd = open(FILE_NAME, O_WRONLY | O_APPEND);
if (fd == -1) {
perror("open");
exit(1);
}
int n = write(fd, buf, strlen(buf));
if (n == -1) {
perror("write");
exit(1);
}
printf("Child process write to file: %s\n", buf);
if (close(fd) == -1) {
perror("close");
exit(1);
}
// 释放 semaphore
if (sem_post(sem) == -1) {
perror("sem_post");
exit(1);
}
exit(0);
} else {
// 父进程
// 等待子进程结束
int status;
waitpid(pid, &status, 0);
waitpid(pid2, &status, 0);
// 删除 semaphore
if (sem_unlink(SEM_NAME) == -1) {
perror("sem_unlink");
exit(1);
}
}
}
return 0;
}
```
下面是第二问另一种实现,使用 strict alternation 算法实现互斥写:
```c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#define FILE_NAME "my_file.txt"
int main() {
// 创建子进程
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
// 子进程
char buf[100];
sprintf(buf, "%sPROC1 %s", getenv("USER") + 4, FILE_NAME);
// 写文件
int fd = open(FILE_NAME, O_WRONLY | O_APPEND);
if (fd == -1) {
perror("open");
exit(1);
}
int n = write(fd, buf, strlen(buf));
if (n == -1) {
perror("write");
exit(1);
}
printf("Child process write to file: %s\n", buf);
if (close(fd) == -1) {
perror("close");
exit(1);
}
exit(0);
} else {
// 父进程
pid_t pid2 = fork();
if (pid2 == -1) {
perror("fork");
exit(1);
}
if (pid2 == 0) {
// 子进程
char buf[100];
sprintf(buf, "%sPROC2 %s", getenv("USER") + 4, FILE_NAME);
// 等待父进程写完
while (access(FILE_NAME, F_OK) == 0) {
usleep(100);
}
// 写文件
int fd = open(FILE_NAME, O_WRONLY | O_APPEND);
if (fd == -1) {
perror("open");
exit(1);
}
int n = write(fd, buf, strlen(buf));
if (n == -1) {
perror("write");
exit(1);
}
printf("Child process write to file: %s\n", buf);
if (close(fd) == -1) {
perror("close");
exit(1);
}
exit(0);
} else {
// 父进程
// 等待子进程结束
int status;
waitpid(pid, &status, 0);
waitpid(pid2, &status, 0);
}
}
return 0;
}
```
阅读全文