美文网首页操作系统
读者-写者问题

读者-写者问题

作者: 大海孤了岛 | 来源:发表于2017-04-06 19:51 被阅读84次
    问题描述
    读者写者.png
    使用信号量进行解决
    信号量
    优先策略选择
    优先策略
    读者优先
    semaphore ReaderWriterMutex = 1;    //实现读写互斥
    int Rcount = 0;             //读者数量
    semaphore CountMutex = 1;   //读者修改计数互斥
    
    writer(){
        while(true){
            P(ReaderWriterMutex);
            write;
            V(ReaderWriterMutex);   
        }
        
    }
    
    reader(){
        while(true){
            P(CountMutex);
            if(Rcount == 0)     //当第一个读者进来时,阻塞写者
                P(ReaderWriterMutex);
            ++Rcount;
            V(CountMutex);
    
            read;
    
            P(CountMutex);
            --Rcount;
            if(Rcount == 0)
                V(ReaderWriterMutex);   //当最后一个读者离开后,释放写者
            V(CountMutex);
        }
    }
    

    上述方案为读者优先。因为当读者进行读取的时候,如果后面一直有读者进入,那么写者就会被阻塞,直到所有读者完成之后,写者才可以进行。

    写者优先
    semaphore ReaderWriterMutex = 1;    //实现读写互斥
    int Rcount = 0;                //读者数量
    semaphore CountMutex = 1;    //读者修改计数互斥
    semaphore WriterMutex = 1;  //用于实现写者优先
    
    writer(){
        while(true){
            P(WriterMutex); //无写进程时进入
            P(ReaderWriterMutex); //互斥访问共享文件
            write;
            V(ReaderWriterMutex);  //释放共享文件
            V(WriterMutex); //恢复对共享文件的访问
        }
    
    }
    
    reader(){
        while(true){
            P(WriterMutex); //无写进程时进入
            P(CountMutex);
            if(Rcount == 0)        //当第一个读者进来时,阻塞写者
                P(ReaderWriterMutex);
            ++Rcount;
            V(CountMutex);
            V(WriterMutex);//恢复对共享文件的访问
    
            read;
    
            P(CountMutex);
            --Rcount;
            if(Rcount == 0)
                V(ReaderWriterMutex);    //当最后一个读者离开后,释放写者
            V(CountMutex);
        }
    }
    

    上述方案为写者优先。设置一个WriterMutex信号量来实现优先读。我们可以看到,当有写者进入时,通过P(WriterMutex)阻塞了读者。

    使用管程方法
    int AR = 0; //表示正在读的读者
    int AW = 0; //表示正在写的写者
    int WR = 0; //表示正在等待的读者
    int WW = 0; //表示正在等待的写者
    
    Lock lock; 
    Condition okToRead; //可以读取
    Condition okToWrite; //可以写入
    
    Database::Read(){
        //Wait until no writers;
        StartRead();
        read database;
        //check out - wake up waiting writers;
        DoneRead();
    }
    
    
    Database::StartRead(){
        lock.Acquire();
        //当存在写者,则阻塞读者
        while((AW + WW) > 0){
            WR ++;
            okToRead.Wait(&lock);
            WR --;
        }
        //读者进行读
        AR++;
        lock.Release();
    }
    
    Database::DoneRead(){
        lock.Acquire();
        //读者完成读
        AR --;
        //当正在读的读者都完成后,唤醒写者
        if(AR == 0 && WW > 0){
            okToWrite.signal();
        }
        lock.Release();
    }
    
    
    
    
    Database::Writer(){
        //Wait until no readers/writers;
        StartWrite();
        writer database;
        //check out - wake up waiting readers/writers;
        DoneWrite();
    }
    
    Database::StartWrite(){
        lock.Acquire();
        //若存在正在读的读者或正在等待的写者,则阻塞当前写者
        while((AR + AW) > 0){
            WW ++;
            okToWrite.Wait(&lock);
            WW --;
        }
        //进行写
        AW++
        lock.Release();
    }
    
    
    Database::DoneWrite(){
        lock.Acquire();
        //写完成
        AW --;
        //写者优先,若存在等待的写者,先唤醒等待的写者
        if(WW > 0){
            okToWrite.signal();
        } else if (WR > 0){
            okToRead.signal();
        }
        lock.Release();
    }
    

    相关文章

      网友评论

        本文标题:读者-写者问题

        本文链接:https://www.haomeiwen.com/subject/dnbqattx.html