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

/*
名称:有名信号量实现读者-写着问题(读者优先)
说明:本实验实现的是读者优先的读者写者问题,即若有读者正在访问文件,而且还有读者和想要申请访问文件,则对于读者可以直接访问,对于写者必须等待所有的读者访问完毕(包括正在访问的和正在申请访问的读者),没有读者时,才能访问文件进行写入。
基本的算法很简单,就不说了。要提到一点的是,本实验花了好几天时间才弄出来,原因是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;
}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值