|
|
@ -0,0 +1,76 @@ |
|
|
|
#include <stdio.h> |
|
|
|
#include <proc.h> |
|
|
|
#include <sem.h> |
|
|
|
#include <monitor.h> |
|
|
|
#include <assert.h> |
|
|
|
|
|
|
|
#define READER_NUM 100 // 读者数量,取值应大于1,小于int范围 |
|
|
|
#define WRITER_NUM 100 // 写者数量,取值应大于1,小于int范围 |
|
|
|
// #define BUFFER_NUM 10 // 缓冲区数量,取值应大于1,小于int范围 |
|
|
|
#define SLEEP_TIME 10 |
|
|
|
|
|
|
|
// down和up、P和V 都实在是用不习惯,还是用acquire和release吧。 |
|
|
|
#define acquire down |
|
|
|
#define release up |
|
|
|
|
|
|
|
semaphore_t mutex; /* 临界区互斥 */ |
|
|
|
semaphore_t synchronization; // 同步 |
|
|
|
int read_pos_write_neg = 0; // 表示正在读取的读者数量 |
|
|
|
int buffer; |
|
|
|
|
|
|
|
int reader(int index){ |
|
|
|
lab6_set_priority(rand() % 100); |
|
|
|
int result; |
|
|
|
acquire(&mutex); |
|
|
|
read_pos_write_neg++; |
|
|
|
if (read_pos_write_neg == 1) |
|
|
|
acquire(&synchronization); |
|
|
|
release(&mutex); |
|
|
|
do_sleep(rand() % SLEEP_TIME); // 模拟读延迟 |
|
|
|
result = buffer; |
|
|
|
acquire(&mutex); |
|
|
|
read_pos_write_neg--; |
|
|
|
assert(read_pos_write_neg >=0); |
|
|
|
if (read_pos_write_neg == 0) { |
|
|
|
release(&synchronization); |
|
|
|
} |
|
|
|
release(&mutex); |
|
|
|
cprintf("reader %2d read %2d\n", index, result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
void writer(int index) { |
|
|
|
lab6_set_priority(rand() % 100); |
|
|
|
int write_data = rand() % 100; |
|
|
|
acquire(&synchronization); |
|
|
|
do_sleep(rand() % SLEEP_TIME); // 模拟写延迟 |
|
|
|
buffer = write_data; |
|
|
|
release(&synchronization); |
|
|
|
cprintf("writer %2d writed %2d\n", index, write_data); |
|
|
|
} |
|
|
|
|
|
|
|
void read_write_sync() { |
|
|
|
sem_init(&mutex, 1); |
|
|
|
sem_init(&synchronization, 1); |
|
|
|
int reader_num = 0, writer_num = 0; |
|
|
|
while (reader_num < READER_NUM || writer_num < WRITER_NUM) { |
|
|
|
if (rand() % 2) { |
|
|
|
if (reader_num < READER_NUM) { |
|
|
|
int pid = kernel_thread(reader, (void *)reader_num, 0); |
|
|
|
if (pid <= 0) { |
|
|
|
panic("create No.%d reader failed.\n"); |
|
|
|
} |
|
|
|
reader_num++; |
|
|
|
} |
|
|
|
} else { |
|
|
|
if (writer_num < WRITER_NUM) { |
|
|
|
int pid = kernel_thread(writer, (void *)writer_num, 0); |
|
|
|
if (pid <= 0) { |
|
|
|
panic("create No.%d writer failed.\n"); |
|
|
|
} |
|
|
|
writer_num++; |
|
|
|
} |
|
|
|
} |
|
|
|
do_sleep(rand() % SLEEP_TIME); // 模拟入队延迟 |
|
|
|
} |
|
|
|
} |