重新编写s0.c,s1.c,s2.c的代码
时间: 2024-11-10 08:26:23 浏览: 7
以下是 `s0.c`, `s1.c` 和 `s2.c` 的重新编写版本,保持原有功能的同时,进行了适当的优化和注释:
### s0.c: 初始状态设置进程
```c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SEM_FILE "sem_name.tmp"
#define EMPTY_FILE "empty.txt"
#define CLIENT_FILE "pvh"
#define FULL_FILE "full.txt"
void sigint_handler(int);
int semid;
struct sembuf psembuf, vsembuf;
int main(int argc, char *argv[]) {
int k = 10, buffer = 1;
char filename[20];
FILE *fempty, *full, *fp[k];
key_t key;
short initarray[3];
signal(SIGINT, sigint_handler);
// 创建并打开SEM_FILE
fempty = fopen(SEM_FILE, "w");
if (fempty == NULL) {
perror("Error opening SEM_FILE for writing");
return 1;
}
// 生成键值
key = ftok(SEM_FILE, 'a');
printf("Key = %u\n", key);
if (key == -1) {
perror("Error generating key");
return 1;
}
// 获取信号量集
semid = semget(key, 3, 0777 | IPC_CREAT);
printf("Semaphore ID = %d\n", semid);
if (semid == -1) {
perror("Error getting semaphore");
return 1;
}
// 初始化信号量
initarray[0] = buffer; // 缓冲池
initarray[1] = k; // 空缓冲区
initarray[2] = 0; // 满缓冲区
if (semctl(semid, 0, SETALL, initarray) == -1) {
perror("Error initializing semaphores");
return 1;
}
// 验证初始化
short outarray[3];
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("Semaphore initial values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
// 关闭SEM_FILE
fclose(fempty);
// 创建EMPTY_FILE和FULL_FILE
fempty = fopen(EMPTY_FILE, "w");
full = fopen(FULL_FILE, "w");
if (fempty == NULL || full == NULL) {
perror("Error opening files for writing");
return 1;
}
// 创建k个空文件并将文件名写入EMPTY_FILE
for (int i = 0; i < k; i++) {
sprintf(filename, "%s%03d.txt", CLIENT_FILE, i);
fp[i] = fopen(filename, "w");
if (fp[i] == NULL) {
perror("Error creating client file");
return 1;
}
fclose(fp[i]);
fprintf(fempty, "%s\n", filename);
}
fclose(full);
fclose(fempty);
// 再次验证信号量值
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("Semaphore values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
getchar();
return 0;
}
void sigint_handler(int sig) {
if (semctl(semid, 0, IPC_RMID, 0) == -1) {
perror("Error removing semaphore");
}
exit(0);
}
```
### s1.c: 写者进程
```c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define SEM_FILE "sem_name.tmp"
#define EMPTY_FILE "empty.txt"
#define FULL_FILE "full.txt"
int semid;
unsigned int count;
struct sembuf psembuf[2], vsembuf[2];
typedef struct {
char str[100];
char num[6];
} Msg;
int main(int argc, char *argv[]) {
int k = 10, area = 0, first = 1, second = 2;
char emptyname[20], restname[k * 20];
FILE *fempty, *full;
key_t key;
short outarray[3];
Msg msg;
// 初始化
memset(emptyname, 0x00, 20);
memset(restname, 0x00, k * 20);
memset(msg.str, 0x00, sizeof(msg.str));
memset(msg.num, 0x00, sizeof(msg.num));
// 生成键值
key = ftok(SEM_FILE, 'a');
printf("Key = %u\n", key);
if (key == -1) {
perror("Error generating key");
return 1;
}
// 获取信号量集
semid = semget(key, 3, 0777);
printf("Semaphore ID = %d\n", semid);
if (semid == -1) {
perror("Error getting semaphore");
return 1;
}
// 设置P操作和V操作
psembuf[0].sem_op = -1;
psembuf[0].sem_flg = SEM_UNDO;
vsembuf[0].sem_op = 1;
vsembuf[0].sem_flg = SEM_UNDO;
psembuf[1].sem_op = -1;
psembuf[1].sem_flg = SEM_UNDO;
vsembuf[1].sem_op = 1;
vsembuf[1].sem_flg = SEM_UNDO;
// 验证初始化
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("Semaphore initial values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
for (count = 0;; count++) {
psembuf[0].sem_num = area;
psembuf[1].sem_num = first;
// P操作
if (semop(semid, psembuf, 2) == -1) {
perror("Error in P operation");
return 1;
}
// 验证信号量值
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("After P, semaphore values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
// 读取EMPTY_FILE中的空缓冲区名称
fempty = fopen(EMPTY_FILE, "r");
full = fopen(FULL_FILE, "a");
fread(emptyname, sizeof(char), 10, fempty);
fwrite(emptyname, strlen(emptyname), sizeof(char), full);
fclose(full);
int i = 0;
while (!feof(fempty)) {
fread(restname + i * 10, sizeof(char), 10, fempty);
i++;
}
printf("Rest restname: (%s)\n", restname);
fclose(fempty);
// 更新EMPTY_FILE
fempty = fopen(EMPTY_FILE, "w");
fwrite(restname, strlen(restname), sizeof(char), fempty);
fclose(fempty);
memset(restname, 0x00, sizeof(restname));
// 构建消息
sprintf(msg.str, "Hello, I am Writer_ pid: %d, msg_no: %d", getpid(), count);
sprintf(msg.num, "%03d", 0); // 假设初始读者数量为0
// 写入空缓冲区
fempty = fopen(emptyname, "w");
fwrite(msg.str, strlen(msg.str), sizeof(char), fempty);
fwrite(msg.num, strlen(msg.num), sizeof(char), fempty);
fclose(fempty);
printf("%s\n", msg.str);
printf("%s\n", msg.num);
// 验证信号量值
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("Semaphore values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
// 如果满缓冲区计数为0,唤醒读者
if (outarray[2] == 0) {
vsembuf[1].sem_num = second;
vsembuf[0].sem_num = area;
if (semop(semid, vsembuf, 2) == -1) {
perror("Error in V operation");
return 1;
}
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("After V area and reader, semaphore values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
} else {
vsembuf[0].sem_num = area;
if (semop(semid, vsembuf, 1) == -1) {
perror("Error in V operation");
return 1;
}
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("After V area, semaphore values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
}
}
return 0;
}
```
### s2.c: 读者进程
```c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define SEM_FILE "sem_name.tmp"
#define EMPTY_FILE "empty.txt"
#define FULL_FILE "full.txt"
#define MAX_MSG_NUM 10000
int semid;
unsigned int count;
struct sembuf psembuf[2], vsembuf[2];
typedef struct {
char str[100];
char num[6];
} Msg;
int main(int argc, char *argv[]) {
int k = 10, n = 2, area = 0, first = 2, second = 1, msg_no = 0, readers = n, receive_msg_no = 0, has_read = 0, empty_add_num = 0;
int Read = 0;
char emptyname[20], restname[k * 20];
FILE *fempty, *full, *fp;
key_t key;
Msg msg;
char receive_msg[MAX_MSG_NUM][100];
short outarray[3];
// 初始化
memset(emptyname, 0x00, 20);
memset(restname, 0x00, k * 20);
memset(msg.str, 0x00, sizeof(msg.str));
memset(msg.num, 0x00, sizeof(msg.num));
for (int i = 0; i < MAX_MSG_NUM; i++)
memset(receive_msg[i], 0x00, 100);
// 生成键值
key = ftok(SEM_FILE, 'a');
printf("Key = %u\n", key);
if (key == -1) {
perror("Error generating key");
return 1;
}
// 获取信号量集
semid = semget(key, 3, 0777);
printf("Semaphore ID = %d\n", semid);
if (semid == -1) {
perror("Error getting semaphore");
return 1;
}
// 设置P操作和V操作
psembuf[0].sem_op = -1;
psembuf[0].sem_flg = SEM_UNDO;
vsembuf[0].sem_op = 1;
vsembuf[0].sem_flg = SEM_UNDO;
psembuf[1].sem_op = -1;
psembuf[1].sem_flg = SEM_UNDO;
vsembuf[1].sem_op = 1;
vsembuf[1].sem_flg = SEM_UNDO;
// 验证初始化
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("Semaphore initial values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
for (count = 0;; count++) {
empty_add_num = 0;
printf("Count = %d, Receive message number = %d\n", count, receive_msg_no);
psembuf[0].sem_num = area;
psembuf[1].sem_num = first;
// P操作
if (semop(semid, psembuf, 2) == -1) {
perror("Error in P operation");
return 1;
}
// 验证信号量值
if (semctl(semid, 0, GETALL, outarray) == -1) {
perror("Error getting semaphore values");
return 1;
}
printf("After P, semaphore values: %d, %d, %d\n", outarray[0], outarray[1], outarray[2]);
// 读取FULL_FILE中的满缓冲区名称
full = fopen(FULL_FILE, "r");
if (full == NULL) {
perror("Error opening full file");
return 1;
}
int i = 0;
memset(restname, 0x00, k * 20);
size_t bytesRead = fread(restname, sizeof(char), 10, full);
while (bytesRead > 0) {
has_read = 0;
fp = fopen(restname, "r");
if (fp == NULL) {
perror("Error opening temp file");
continue;
}
fgets(msg.str, 100, fp);
fgets(msg.num, 10, fp);
printf("File: %s, Message: %s\n", restname, msg.str);
printf("File: %s, Number: %s\n", restname, msg.num);
for (int j = 0; j < receive_msg_no && !has_read; j++) {
if (strcmp(receive_msg[j], msg.str) == 0) {
printf("The message has been read!\n");
has_read = 1;
}
}
if (has_read) {
memset(restname, 0x00, k * 20);
bytesRead = fread(restname, sizeof(char), 10, full);
fclose(fp);
continue;
} else {
strcpy(receive_msg[(receive_msg_no++) % MAX_MSG_NUM], msg.str);
}
printf("Message number: %d\n", atoi(msg.num));
if (atoi(msg.num) == 2495) {
empty_add_num++;
printf("I am the last reader for file: %s, I will empty it and add its name to file: %s!\n", restname, EMPTY_FILE);
printf("%s\n", msg.str);
printf("%s\n", msg.num);
fclose(fp);
fp = fopen(restname, "w");
if (fp == NULL) {
perror("Error opening temp file for writing");
continue;
}
fclose(fempty);
fempty = fopen(EMPTY_FILE, "a");
if (fempty == NULL) {
perror("Error opening empty file for appending");
continue;
}
fwrite(restname, strlen(restname), sizeof(char), fempty);
fclose(fempty);
memset(restname, 0x00, k * 20);
i = 0;
bytesRead = fread(restname + i * 10, sizeof(char), 10, full);
while (bytesRead > 0) {
i++;
bytesRead = fread(restname + i * 10, sizeof(char), 10, full);
}
printf("Rest restname: (%s)\n", restname);
fclose(full);
full = fopen(FULL_FILE, "w");
if (full == NULL) {
perror("Error opening full file for writing");
continue;
}
fwrite(restname, strlen(restname),
阅读全文