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

来源:互联网 发布:阿里云真实性核验单 编辑:程序博客网 时间:2024/04/30 18:38

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