/*
名称:有名信号量实现读者-写着问题(读者优先)
说明:本实验实现的是读者优先的读者写者问题,即若有读者正在访问文件,而且还有读者和想要申请访问文件,则对于读者可以直接访问,对于写者必须等待所有的读者访问完毕(包括正在访问的和正在申请访问的读者),没有读者时,才能访问文件进行写入。
基本的算法很简单,就不说了。要提到一点的是,本实验花了好几天时间才弄出来,原因是C掌握不熟,把共享的字符指针sha_buf = “helloworld”.直接赋值,然后用通过sprintf修改sha_buf的内容。其实,此时sha_buf指向是一块字符常量了,不是原来申请的那块共享内存了。大二之后,C语言用的就少了,基本的都忘了。以后得抽空,好好看看C语言了。
*/
读者:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#define SIZE 4096
//创建模式权限
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(int argc,char **argv)
{
sem_t * mut_cou = NULL; /* 用于读者数量的互斥访问*/
sem_t * rw = NULL; //用于读者和写着之间互斥访问共享文件
int *rea_cou = NULL; //共享的变量,用于保存当前读者的人数
char * sha_buf = NULL; //共享缓冲区,模拟共享文件
int shm_fd = 0; //用于映射共享内存
int wait_time = 0;
//创建mutex_count信号量,初始值为1
if((mut_cou = sem_open("mutex_count",O_CREAT,FILE_MODE,1)) == SEM_FAILED)
{
printf("sem_open 1 %s Error\n",argv[0]);
exit(-1);
}
//创建rw信号量,初始值为1
if((rw = sem_open("rw",O_CREAT,FILE_MODE,1)) == SEM_FAILED)
{
printf("sem_open 2 %s Error\n",argv[0]);
exit(-1);
}
//创建共享内存空间
/* create the shared memory segment */
shm_fd = shm_open("buf", O_CREAT | O_RDWR, 0666);
/* configure the size of the shared memory segment */
ftruncate(shm_fd,SIZE);
/* now map the shared memory segment in the address space of the process */
sha_buf =(char*) mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (sha_buf == MAP_FAILED) {
printf("Map buf failed\n");
return -1;
}
//创建共享变量(读者数量)内存空间
/* create the shared memory segment */
shm_fd = shm_open("rea_cou", O_CREAT | O_RDWR, 0666);
/* configure the size of the shared memory segment */
ftruncate(shm_fd,1);
/* now map the shared memory segment in the address space of the process */
rea_cou = (int *)mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (rea_cou == MAP_FAILED) {
printf("Map count failed\n");
return -1;
}
while(1)
{
sem_wait(mut_cou); //申请访问变量rea_cou(正在读文件的人数)
if(0 == *rea_cou) //如果当前人数为0,则要申请互斥信号量rw
sem_wait(rw);
++(*rea_cou); //读者+1
sem_post(mut_cou); //释放变量访问锁
printf("I am reader process .My pid is %d.",getpid());
printf("I am reading the file.And the content is %s\n",sha_buf);
sem_wait(mut_cou); //申请访问变量rea_cou,准备修改rea_cou
--(*rea_cou); //读者-1
if(0 == (*rea_cou)) //如果是最后一个读者的话,则释放共享文件访问锁
sem_post(rw);
sem_post(mut_cou); //释放变量访问锁
wait_time = rand()%5;
sleep(wait_time); //随机休息
}
return 0;
}
写者:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#define SIZE 4096
//创建模式权限
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main(int argc,char **argv)
{
sem_t * mut_cou = NULL; /* 用于读者数量的互斥访问*/
sem_t * rw = NULL; //用于读者和写着之间互斥访问共享文件
int *rea_cou = NULL; //共享的变量,用于保存当前读者的人数
char * sha_buf = NULL; //共享缓冲区,模拟共享文件
int shm_fd = 0; //用于映射共享内存
int wait_time = 0;
pid_t pid = getpid();
//创建mutex_count信号量,初始值为1
if((mut_cou = sem_open("mutex_count",O_CREAT,FILE_MODE,1)) == SEM_FAILED)
{
printf("sem_open 1 %s Error\n",argv[0]);
exit(-1);
}
//创建rw信号量,初始值为1
if((rw = sem_open("rw",O_CREAT,FILE_MODE,1)) == SEM_FAILED)
{
printf("sem_open 2 %s Error\n",argv[0]);
exit(-1);
}
//创建共享内存空间
/* create the shared memory segment */
shm_fd = shm_open("buf", O_CREAT | O_RDWR, 0666);
/* configure the size of the shared memory segment */
ftruncate(shm_fd,SIZE);
/* now map the shared memory segment in the address space of the process */
sha_buf =(char*) mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (sha_buf == MAP_FAILED) {
printf("Map buf failed\n");
return -1;
}
//创建共享变量(读者数量)内存空间
/* create the shared memory segment */
shm_fd = shm_open("rea_cou", O_CREAT | O_RDWR, 0666);
/* configure the size of the shared memory segment */
ftruncate(shm_fd,1);
/* now map the shared memory segment in the address space of the process */
rea_cou = (int *)mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (rea_cou == MAP_FAILED) {
printf("Map count failed\n");
return -1;
}
sprintf(sha_buf,"%d writer recorded the infomation",pid); //初始化共享内存区域
while(1)
{
sem_wait(rw); //申请访问“文件”
printf("I am %d writer.I am writing to the file.\n",pid);
sprintf(sha_buf,"%d writer recorded the infomation",pid);
sem_post(rw); //释放“文件”
wait_time = rand()%5;
sleep(wait_time); //随机休息
}
return 0;
}