精华内容
下载资源
问答
  • 读者 写者 实验报告的啊 读者 写者 实验报告的啊 读者 写者 实验报告的啊 读者 写者 实验报告的啊 读者 写者 实验报告的啊 读者 写者 实验报告的啊
  • 读者/写者问题实验报告 ――多线程的实现
  • 读者写者问题实验报告 有代码有流程图 使用PV原语做题
  • 创建一个控制台进程。此进程包含n个线程。用这n个线 程来表示n个读者写者。每个线程按相应测试数据文件 (后面有介绍)的要求进行读写操作。用信号量机制分别实 现读者优先和写者优先的读者-写者问题
  • 操作系统实验报告_读者写者问题.doc 含源代码,实验报告
  • 1、读/互斥访问;2、/互斥访问;3、允许多个读者同时对文件进行访问。
  • 目 录 一 设计概 述 3 二 设计 目的与内 容 4 三 设计分 析 5 四 程序实 现 6 五 程序调 试 7 六 结果分析和讨 论 7 七 心得体 会 8 八 源代码 8 一 设计概述 所谓读者写者问题是指保证一个writer进程必须与其他进程...
  • 操作系统读者写者问题实验报告,内附程序源码,实验结果图等,详细易懂
  • PAGE PAGE 1 操作系统原理课程设计 课程设计起止时间2009年 指导教师 成绩 课程设计成绩评定表 质量评价指标 评 价 项 目 具 体 要 求 满 分 得 分 学习态度 学习认真态度端正遵守纪律出勤情况良好能够独立完成设计...
  •   以读者写者问题为例,学习并熟悉Linux下进程通信、同步机制的具体实现方法,主要是了解并掌握信号量机制的使用方法,进一步熟悉Linux系统的相关指令的调用。 【实验内容】   在Linux环境下,创建一个控制台...

    【注意】代码在文末,以下为详细实验报告

    【实验目的】

      以读者写者问题为例,学习并熟悉Linux下进程通信、同步机制的具体实现方法,主要是了解并掌握信号量机制的使用方法,进一步熟悉Linux系统的相关指令的调用。

    【实验内容】

      在Linux环境下,创建一个控制台进程,此进程包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应进行读写操作。用信号量机制分别实现读者优先和写者优先的读者-写者问题。
      读者-写者问题的读写操作限制(包括读者优先和写者优先):
      写-写互斥,即不能有两个写者同时进行写操作。
      读-写互斥,即不能同时有一个线程在读,而另一个线程在写。
      读-读允许,即可以有一个或多个读者在读。
      读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。
      写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态才能开始读操作。

    【实验环境】(含主要设计设备、器材、软件等)
    在这里插入图片描述

    【实验步骤、过程】(含原理图、流程图、关键代码,或实验过程中的记录、数据等)

    一、数据结构

      读者写者问题中,共定义了以下两个数据结构,分别是共享内存和readcount,详细定义内容如下所示
    在这里插入图片描述

                图1 共享内存数据结构

    在这里插入图片描述

                图2 readcount数据结构

    二、算法描述

    大致可以分为以下两个部分

    1.读者优先

    (1)初始化,产生共享内存并初始化共享内存,初始读取的进程为0个,将信号量集中的互斥读取信号量和文件资源信号量进行初始化,在后续读者写者进程运行时会对内容改写。
    在这里插入图片描述

                图3 初始化

    (2)读者先通过p操作访问Readcount资源,通过Readcount是否为0判断该进程是否为第一个读者进程,若为第一个读者进程则取得文件资源信号量然后Readcount++,再通过v操作退出访问Readcount资源此后调用read()函数读取临界资源,在退出临界资源也与进入时一样,需判断是否为第一个读者进程,若是则需对file信号量进行v操作
    在这里插入图片描述

              图4 读者访问资源readcount

    (3)写者进程在一开始的时候就需要对file信号量进行p操作以申请访问临界资源,在没有其他进程使用临界资源是才可以进入,从而实现了读者优先。

    2.写者优先

      在写者优先问题中,相较于读者优先,在读进程里增加一个信号量,让读进程与写进程公平竞争前需要先争夺该信号量实现写进程优先。
    在这里插入图片描述

              图5 写者优先主要代码
    在这里插入图片描述

                  图6 写进程

    3.原子操作

      实现的P操作,通过得到信号量集的id并获取需要操作的信号量对其信号量进行-1操作。
    在这里插入图片描述

                图7 P操作

      实现V操作,通过得到信号量集的id并获取需要操作的信号量对其进行+1操作。
    在这里插入图片描述

                图8 V操作

    三、程序流程图

    1.读者优先
    在这里插入图片描述

              图9 读者优先流程图

    2.写者优先
    在这里插入图片描述

              图10 写者优先流程图

    四、伪代码描述

    1.读者优先

    int readcount=0;
    semaphore rmutex=1;    
    semaphore wmutex=1;        
    writer()
    {
        while(1)
        {
            P(rmutex);
    		…
            Perform write operation
    		…
            V(wmutex);
        }
    }
    reader()
    {
        while(1)
        {
            P(rmutex);
            if(count==0)
                P(wmutex);
            readcount++;
            V(rmutex);
            …
            Perform read operation
    		…
            P(rmutex);
            readcount--;
            if(count==0)
                V(wmutex);
            V(rmutex)}
    }
    

    2.写者优先

    int Writercount=0; 
    int Readercount=0; 
    semaphore wmutex=1; 
    semaphore rmutex=1;    
    semaphore wpmutex=1; 
    semaphore source=1; 
    writer()
    {
        while(1)
        {
            P(wmutux);
            if(Writercount==0)
                P(wpmuex); 
            Writercount++;
            V(wmutux)
            P(souce); 
            …
            Perform write operation
    		…
            V(souce);
            P(wmutux);
            Writercount--;
            if(Writercount==0)
                V(wpmutex);
            V(wmutux);
        }
    }
    reader()
    {
        while(1)
        {
            P(wpmutex); 
            P(rmutex);
            if(Readercount==0)
                P(souce);
            Readercount++;
            V(rmutex);
            V(wpmutex);
            …
            Perform read operation
    		…
            P(r_mutex);
            Readercount--;
            if(Readercount==0)
                V(souce);
            V(rmutex);
        }
    }
    

    五、编译指令

    //读者优先
    $ gcc -o r_first.out r_first.c
    $ ./r_first.out
    //写者优先
    $ gcc -o w_first.out w_first.c
    $ ./w_first.out
    

              图11 所有编译指令

    六、运行结果

    1.读者优先

    在这里插入图片描述
    在这里插入图片描述

              图12 r_first.c运行结果

    2.写者优先
    在这里插入图片描述
    在这里插入图片描述

              图13 w_first.c运行结果

    【实验结果或总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见)

      在读者优先中,如果读者获得了访问权,那么当一个进程读完,另一个也可以开始进行读,但是如果写进程获得了访问权,而读者可以优先获得临界区的访问权,从而写进程被阻塞,进入阻塞队列,因此,在读者优先中,写进程只有等待没有读者访问临界区的时候,才能得到临界区的访问权,而此时读者在任意时候都可以得到临界区的访问权。
      在写者优先中,如果读者获得了访问权,那么当一个进程读完,另一个也可以开始进行读,但是如果读进程获得了访问权,而写者可以优先获得临界区的访问权,从而读进程被阻塞,进入阻塞队列,等此时的读者刚执行完V操作时,那么写者就可以进程P操作继续执行了。因此,在写者优先中,我们需要增加一个信号量,让读进程与写进程公平竞争前需要先争夺该信号量实现写进程优先。
      设想当一个读者在读数据,另一个读者也来访问,由于同时允许多个读者同时进行读操作,所以第二个读者也被允许进入,同理第三个读者也被允许进入。现在假设一个写者到来,由于写操作是排他的,所以它不能写数据,而是被阻塞。随后其他的读者到来,这样只要有一个读者活跃,随后而来的读者都被允许访问数据。这样的结果是只要有读者陆续到来,它们一来就被允许进入,而写者将一直被挂起直到没有一个读者为止。
      这次作业让我加深了对于信号量机制以及进程同步的理解,也让学到了许多东西,只有理论与实践相结合,才能把知识学得更加牢固更加扎实。
      最后,感谢倪福川老师以及其他同学给予我的帮助。

    代码

    #include <stdio.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <stdlib.h>
    #define SHM_SIZE (1024*1024)
    #define SHM_MODE 0600
    #define SEM_MODE 0600
    
    #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
    #else
    
    #define n 4
    #define DELAY (rand() % 5 + 1)
    
    union semun
    {
        int val;
        struct semid_ds *buf;
        unsigned short *array;
    };
    #endif
    
    int semid=-1,shmId=-1;
    
    struct readcount
    {
        int read;
        int l;
    }*rdc;
    
    //reader process
    void reader(int i)
    {
        sleep(DELAY);
        printf("This is process %d,and there are %d are reading\n",i,rdc->read);
    }
    //writer process
    void writer()
    {
        sleep(DELAY);
         printf("This is the writing process\n");
    }
    
    void wait(int semid,int i)
    {
        struct sembuf sb;
        sb.sem_num = i;
        sb.sem_op = -1;
        sb.sem_flg = SEM_UNDO;
        if(semop(semid,&sb,1) < 0)
        {
            perror("Wait Failed");
            exit(1);
        }
    }
    void signal(int semid,int i)
    {
        struct sembuf sb;
        sb.sem_num = i;
        sb.sem_op = 1;
        sb.sem_flg = SEM_UNDO;
        if(semop(semid,&sb,1) < 0)
        {
            perror("Signal Failed");
            exit(1);
        }
    }
    
    void init() //initialization
    {
        //share readcount
        if((shmId = shmget(IPC_PRIVATE,SHM_SIZE,SHM_MODE)) < 0)
        	{
        		perror("Create Chared Memory Failed");
        		exit(1);
        	}
        rdc = (struct readcount*)shmat(shmId,0,0);
        rdc->read= 0;
        semid = semget(IPC_PRIVATE,3,IPC_CREAT | 0666);
        if(semid < 0) 
        {
            perror("Create Semaphore Failed");
        	exit(1);
        }
        union semun sem;
        sem.val = 1;
        //exclusive read
        if(semctl(semid,0,SETVAL, sem) < 0)
        {
        	perror("Semctl Failed");
        	exit(1);
        }
        sem.val = 0;
        //readcount count
        if(semctl(semid,1,SETVAL, sem) < 0)
        {
        	perror("Semctl Failed");
        	exit(1);
        }
        sem.val = 1;
        //source
        if(semctl(semid,2,SETVAL, sem) < 0)
        {
        	perror("Semctl Failed");
        	exit(1);
        }
    }
    
    int main()
    {
        init();
        int i=-1,child=-1;
        for(i=0;i<n;i++)
        {
            if((child = fork()) < 0)
        		{
        			perror("Fork Failed");
        			exit(1);
        		}
        		else if(child == 0)
        		{
        			printf("This is the kid %d , pid = %d , ppid = %d\n",i,getpid(),getppid());
        			while(1)
        			{
        				Wait(semid,0);
        				if(rdc->read==0)
                            Wait(semid,2);
        				rdc->read = rdc->read + 1;
        				Signal(semid,0);
        				reader(i);
        				Wait(semid,0);
                        rdc->read--;
                        printf("%d process have read\n",i);
                        if(rdc->read==0)
                            Signal(semid,2);
        				Signal(semid,0);
        				sleep(2);
        			}
        			break;
        		}
        }
        if(child > 0) //parent process
        	{
        		while(1)
        		{
        			Wait(semid,2);
        			writer();
        			Signal(semid,2);
        		}
        	}
        	return 0;
    }
    
    展开全文
  • 在Windows2000环境下 创建一个控制台进程 此进程包含n个线程 用这n个线程来表示n个读者写者 每个线程按相应测试数据文件 后面有介绍 的要求进行读写操作 用信号量机制分别实现读者优先和写者优先的读者 写者问题 ...
  • 本次实验要求使用信号量实现读者写者问题,其中包含读者优先与写者优先两种情况,实验目的:(1)运用信号量来实现读者写者问题(2)熟悉PV原语、信号量的运用。 本资源包括实验报告与实验代码
  • 读者写者问题(java)

    2014-05-24 22:11:00
    读者写者问题
  • 读者写者问题java源代码

    热门讨论 2010-12-26 14:12:46
    读者写者问题java源代码。在myeclipse下调试无误,可以用于操作系统实验报告或研究学习多线程。
  • 沈 阳 理 工 大 学 课 程 设 计 专 用 纸 课程设计任务书 No1 学 院 信息学院 专 业 计算机科学与技术 学 生 姓 名 学 号 题 目 读者写者问题进程同步问题 内容及要求 内容 读者写者问题进程同步问题 实验目的...
  • 操作系统课程设计 课 题读者写者问题 姓 名赫前进 班 级1020552 学 号?102055211 指导教师叶瑶 提交时间2012/12/30 一实验目的 1.进一步理解?临界资源?的概念 2.把握在多个进程并发执行过程中对临界资源访问时的必要...
  • 汇编语言中的读者-写者问题实现以及实验报告
  • 操作系统 读者写者问题c++
  • 有五个哲学家围坐在一圆桌旁,桌中央有一盘通心粉,每人面前有一只空盘子,每两人之间放一只筷子每个哲学家的行为是思考...阅读可以同时访问数据集,而写入只能互斥的访问数据集,不能与任何的进程一起访问数据区。
  • windows内核实验教程 读者写者源代码
  • 是线程同步问题读者写者算法,包括读者优先和写者优先。里面有实验报告,详细说明了实验原理及执行过程,字数够了吗吗
  • 沈阳理工大学课程设计专用纸 No1 课程设计任务书 学 院 信息学院 专 业 计算机科学与技术 学 生 姓 名 学 号 题 目 读者写者问题进程同步问题 内容及要求 内容 读者写者问题进程同步问题 实验目的了解进程同步的...
  • 沈阳理工大学课程设计专用纸 No1 课程设计任务书 学 院 信息学院 专 业 计算机科学与技术 学 生 姓 名 学 号 题 目 读者写者问题进程同步问题 内容及要求 内容 读者写者问题进程同步问题 实验目的了解进程同步的...
  • 是读进程具有优先权的读者写问题。用信号量实现。在Linux下运行。C语言编写。程序绝对可以运行。是理解操作系统的进程并行的一个非常重要的实验
  • 读者写者代码

    2015-05-06 19:12:30
    读者写者代码 大学操作系统课程的实验报告代码
  • cout数据,线程ID:"(); Sleep(2000); /* 执行操作 */ V(Wmutex); cout授权读,线程ID:"(); P(Amutex); authFlag=1; while(waitAuthCount>0){ V(Authmutex); waitAuthCount--; } V(Amutex);...

    【vc++代码】




    【vc++代码】

    // testsemaphore.cpp : Defines the entry point for the console application.
    // by 西南大学计算机科学系周竹荣,系主任,硕导
    //

    #include "stdafx.h"
    #include "windows.h"
    #include "process.h"
    #include<iostream>
    #include <time.h>
    using namespace std;


    #define P(S) WaitForSingleObject(S,INFINITE)//定义Windows下的P操作
    #define V(S) ReleaseSemaphore(S,1,NULL)//定义Windows下的V操作
    HANDLE Wmutex, Rmutex ,Authmutex,Amutex;
    int Rcount = 0;
    int waitAuthCount=0;
    int authFlag=1;

    DWORD WINAPI reader(){
    P(Amutex);
    if (authFlag==0)
    {
    waitAuthCount++;
    cout<<"等待授权,线程ID:"<<GetCurrentThreadId()<<endl;
    P(Authmutex);
    }
    V(Amutex);
    P(Rmutex);
    if (Rcount == 0)
    P(Wmutex);
    Rcount = Rcount + 1;
    V(Rmutex);
    cout<<"读数据,线程ID:"<<GetCurrentThreadId()<<endl;
    Sleep(500); /* 执行读操作 */
    P(Rmutex);
    Rcount = Rcount - 1;
    if (Rcount == 0)
    V(Wmutex);
    V(Rmutex);
    return 1;
    };

    DWORD WINAPI writer(){

    if(Rcount>0)
    {
    cout<<"取消授权,线程ID:"<<GetCurrentThreadId()<<endl;
    authFlag=0;
    }
    P(Wmutex);

    cout<<"写数据,线程ID:"<<GetCurrentThreadId()<<endl;
    Sleep(2000); /* 执行写操作 */
    V(Wmutex);
    cout<<"授权读,线程ID:"<<GetCurrentThreadId()<<endl;
    P(Amutex);
    authFlag=1;
    while(waitAuthCount>0){
    V(Authmutex);
    waitAuthCount--;
    }
    V(Amutex);
    return 1;
    };
    int main(int argc, char* argv[])
    {


    Wmutex=CreateSemaphore(NULL,1,1,NULL);
    Rmutex=CreateSemaphore(NULL,1,1,NULL);
    Authmutex=CreateSemaphore(NULL,1,1,NULL);
    Amutex=CreateSemaphore(NULL,1,1,NULL);

    while(1){
    Sleep(100);
    srand((unsigned)time(NULL));
    int rC=rand()%1000;
    Sleep(rC);
    if( rC % 6==0)
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)writer,NULL,NULL,NULL);
    else
    CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)reader,NULL,NULL,NULL);
    }

    Sleep(600000);
    return 0;
    }


     

    【运行结果】

     

    参考文献

    [1]计算机操作系统-郁红英-冯庚豹-人民邮电出版社

    展开全文
  • 实验报告完整详尽,实现了读者写者的操作控制,代码中有详尽的注释,是操作系统课设不错的例子!
  • 操作系统,读者写者,写优先,实现全部课设要求,有计数器,暂停,读取外部文件供能,使用表格动态的显示数据。简单易懂,源代码和实验报告一起打包,秒过课设。
  • 使用信号量实现有限缓冲区的生产者和消费者问题 使用信号量实现读进程具有优先权的读者写者问题 实验报告(内容、环境、遇到的问题及解决、源代码、流程图、总结) 源代码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,978
精华内容 3,591
关键字:

读者写者问题实验报告