c语言读者写者问题代码
时间: 2024-06-13 18:01:34 浏览: 107
以下是C语言实现读者写者问题的代码,使用信号量机制:
引用:使用POSIX信号量机制解决读者-写者问题C语言实现,读者和写者进程数量可设置。[^1]
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <semaphore.h>
#include <sys/mman.h>
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
// 全局变量
static sem_t *r_lock; // 读者锁
static sem_t *rw_lock; // 写者锁
static int *read_cnt; // 读者数量计数器
static int *data; // 共享数据区
// 读者线程
void *reader(void *arg) {
int id = *(int *)arg;
while (1) {
// 读者锁加锁
sem_wait(r_lock);
(*read_cnt)++;
if (*read_cnt == 1) {
sem_wait(rw_lock);
}
// 读者锁解锁
sem_post(r_lock);
// 读取数据
printf("Reader %d is reading data: %d\n", id, *data);
// 读者锁加锁
sem_wait(r_lock);
(*read_cnt)--;
if (*read_cnt == 0) {
sem_post(rw_lock);
}
// 读者锁解锁
sem_post(r_lock);
// 等待一段时间
sleep(rand() % 3 + 1);
}
return NULL;
}
// 写者线程
void *writer(void *arg) {
int id = *(int *)arg;
while (1) {
// 写者锁加锁
sem_wait(rw_lock);
// 写入数据
(*data)++;
printf("Writer %d is writing data: %d\n", id, *data);
// 写者锁解锁
sem_post(rw_lock);
// 等待一段时间
sleep(rand() % 3 + 1);
}
return NULL;
}
int main(int argc, char *argv[]) {
// 获取参数
if (argc != 3) {
printf("usage: %s <reader_num> <writer_num>\n", argv);
exit(1);
}
int reader_num = atoi(argv);
int writer_num = atoi(argv);
// 创建共享内存
int fd = shm_open("/shm", O_CREAT | O_RDWR, FILE_MODE);
ftruncate(fd, sizeof(sem_t) * 2 + sizeof(int) * 2);
r_lock = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
rw_lock = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, sizeof(sem_t));
read_cnt = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, sizeof(sem_t) * 2);
data = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, sizeof(sem_t) * 2 + sizeof(int));
// 初始化信号量
sem_init(r_lock, 1, 1);
sem_init(rw_lock, 1, 1);
// 创建读者线程
pthread_t tid[reader_num + writer_num];
int index = 0;
for (int i = 0; i < reader_num; i++) {
int *id = malloc(sizeof(int));
*id = ++index;
pthread_create(&tid[i], NULL, reader, id);
}
// 创建写者线程
for (int i = 0; i < writer_num; i++) {
int *id = malloc(sizeof(int));
*id = ++index;
pthread_create(&tid[reader_num + i], NULL, writer, id);
}
// 等待线程结束
for (int i = 0; i < reader_num + writer_num; i++) {
pthread_join(tid[i], NULL);
}
// 销毁信号量
sem_destroy(r_lock);
sem_destroy(rw_lock);
// 删除共享内存
munmap(r_lock, sizeof(sem_t));
munmap(rw_lock, sizeof(sem_t));
munmap(read_cnt, sizeof(int));
munmap(data, sizeof(int));
shm_unlink("/shm");
return 0;
}
```
引用:使用System V信号量机制解决读者-写者问题C语言实现,读者和写者进程数量可设置。
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
// 定义信号量操作
static struct sembuf sem_r_lock = {
{0, 0, SEM_UNDO},
{0, 1, SEM_UNDO},
};
static struct sembuf sem_r_unlock = {
{0, -1, SEM_UNDO},
};
static struct sembuf sem_rw_lock = {
{1, 0, SEM_UNDO},
{0, 0, SEM_UNDO},
};
static struct sembuf sem_rw_unlock = {
{1, -1, SEM_UNDO},
};
// 全局变量
static int sem_id; // 信号量ID
static int *read_cnt; // 读者数量计数器
static int *data; // 共享数据区
// 读者线程
void *reader(void *arg) {
int id = *(int *)arg;
while (1) {
// 读者锁加锁
semop(sem_id, sem_r_lock, 2);
(*read_cnt)++;
if (*read_cnt == 1) {
semop(sem_id, sem_rw_lock, 2);
}
// 读者锁解锁
semop(sem_id, sem_r_unlock, 1);
// 读取数据
printf("Reader %d is reading data: %d\n", id, *data);
// 读者锁加锁
semop(sem_id, sem_r_lock, 2);
(*read_cnt)--;
if (*read_cnt == 0) {
semop(sem_id, sem_rw_unlock, 1);
}
// 读者锁解锁
semop(sem_id, sem_r_unlock, 1);
// 等待一段时间
sleep(rand() % 3 + 1);
}
return NULL;
}
// 写者线程
void *writer(void *arg) {
int id = *(int *)arg;
while (1) {
// 写者锁加锁
semop(sem_id, sem_rw_lock, 2);
// 写入数据
(*data)++;
printf("Writer %d is writing data: %d\n", id, *data);
// 写者锁解锁
semop(sem_id, sem_rw_unlock, 1);
// 等待一段时间
sleep(rand() % 3 + 1);
}
return NULL;
}
int main(int argc, char *argv[]) {
// 获取参数
if (argc != 3) {
printf("usage: %s <reader_num> <writer_num>\n", argv);
exit(1);
}
int reader_num = atoi(argv);
int writer_num = atoi(argv);
// 创建共享内存
int shmid = shmget(IPC_PRIVATE, sizeof(int) * 2, IPC_CREAT | 0666);
read_cnt = (int *)shmat(shmid, 0, 0);
data = read_cnt + 1;
// 初始化共享内存
*read_cnt = 0;
*data = 0;
// 创建信号量
sem_id = semget(IPC_PRIVATE, 2, IPC_CREAT | 0666);
semctl(sem_id, 0, SETVAL, 1);
semctl(sem_id, 1, SETVAL, 1);
// 创建读者线程
pthread_t tid[reader_num + writer_num];
int index = 0;
for (int i = 0; i < reader_num; i++) {
int *id = malloc(sizeof(int));
*id = ++index;
pthread_create(&tid[i], NULL, reader, id);
}
// 创建写者线程
for (int i = 0; i < writer_num; i++) {
int *id = malloc(sizeof(int));
*id = ++index;
pthread_create(&tid[reader_num + i], NULL, writer, id);
}
// 等待线程结束
for (int i = 0; i < reader_num + writer_num; i++) {
pthread_join(tid[i], NULL);
}
// 删除信号量
semctl(sem_id, 0, IPC_RMID, 0);
// 删除共享内存
shmdt(read_cnt);
shmctl(shmid, IPC_RMID, 0);
return 0;
}
```
阅读全文