有名信号量实现读者-写着问题(写者优先)

/*
名称:有名信号量实现读者-写着问题(写者优先)
说明:本实验实现的是写者优先的读者写者问题。和读者优先类似,写者优先是当读者写者在同时申请访问文件时(如果有写者正在写入文件),那么其他写者能更容易的访问到文件(因为“它不用排队”,即在本实验中不用等待queue信号量)。
打个不确切的比方,就像是“读者”和“写者”两个人去买票,本应该老老实实都该排队。但如果“写者”在队伍的前面有熟人(有其他写者正在写入),那么它就可以不用在后面等,类似于插个队(插在熟人写者后面),等熟人写者买完票之后,它就可以买票。这就是写者优先。
读者优先也类似,不同的是,读者在买票的过程中如果遇到熟人,它就可以和熟人一起买票(同时访问文件)。
具体实现的算法,和以前写的“读者优先类似”。需要有一个保存正在访问,更确切的说是等待“队伍”前面的写者人数,如果这个变量不等于0,则其他写者不用等待queue信号量。(不用排队)。
而对于读者,每次访问文件都得老老实实申请queue信号量(排队)。

*/

读者:

#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;          //用于读者和写着之间互斥访问共享文件

    sem_t * queue = 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);
    }  

    //创建排队信号量,初始值为1
    if((queue = sem_open("queue",O_CREAT,FILE_MODE,1)) == SEM_FAILED)
    {
          printf("sem_open 3 %s Error\n",argv[0]);
          exit(-1);
    }  



    //创建共享内存空间
    shm_fd = shm_open("buf", O_CREAT | O_RDWR, 0666);
    ftruncate(shm_fd,SIZE);
    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(queue);        //申请排队信号量
        sem_wait(mut_cou);      //申请访问变量rea_cou(正在读文件的人数)
        if(0 == *rea_cou)       //如果当前人数为0,则要申请互斥信号量rw
            sem_wait(rw);
        ++(*rea_cou);           //读者+1
        sem_post(mut_cou);      //释放变量访问锁
        sem_post(queue);


        printf("I am reader process .My pid is %d.",pid);
        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;          //用于读者和写着之间互斥访问共享文件

    sem_t * queue = NULL;

    int * wr_cou;

    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);
    }  

    //创建排队信号量,初始值为1
    if((queue = sem_open("queue",O_CREAT,FILE_MODE,1)) == SEM_FAILED)
    {
          printf("sem_open 3 %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;
    }

    //创建共享变量(写者数量)内存空间
    shm_fd = shm_open("wr_cou", O_CREAT | O_RDWR, 0666);
    ftruncate(shm_fd,1);
    wr_cou = (int *)mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
    if (wr_cou == MAP_FAILED) {
        printf("Map count  failed\n");
        return -1;
    }

    while(1)
    {

        sem_wait(rw);       //申请访问文件
        if(0 == *wr_cou)    //如果是第一个写者,则需要排队。
            sem_wait(queue);
        ++(*wr_cou);        //写者人数加1


        printf("I am %d writer.I am writing to the file.\n",pid);
        sprintf(sha_buf,"%d writer recorded the infomation",pid);

        --(*wr_cou);        //写者人数减1
        if(0 == *wr_cou )   //如果是最后一个写者则释放queue
            sem_post(queue);
        sem_post(rw);

        wait_time = rand()%5;
        sleep(wait_time);   //随机休息

    }

    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值