欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

读写者问题

程序员文章站 2022-03-05 09:56:05
...

**

读写者

**

读写者问题

只要求读文件的进程称为reader进程,其他进程称为writer进程。
允许多个进程同时读一个共享对象,但不允许一个writer进程和其他reader进程同时或writer进程同时访问一个共享对象。
简单来说,读写者问题是保证一个writer进程必须与其他进程互斥的访问共享对象的同步问题。
三句话来说,就是:
读读共享;写写互斥;读写互斥

读者-写者问题是一个经典的并发程序设计问题,是经常出现的一个同步问题。
如果读者来:

无读者、写者,新读者可以读
有写者等待,但有其他读者正在读,新读者可以读
有写者写,新读者等

如果写者来:

无读者,新写者可以写
有读者,新写者等待
有其他写者,新写者等待

现在开始分析读写者的

解决方案

读进程优先**

无需修改就可用于多个读进程和写进程的情况。写进程非常简单,信号量用于实施互斥,只要一个写进程正在访问共享数据区,其他的写进程和读进程都不能访问它。读进程也使用信号量实施互斥,但是,为允许多个读进程,当没有读进程正在读时,第-一个试图读的读进程需要在信号量上等待。当至少已经有一个读进程在读时,随后的读进程无需等待,可以直接进入。全局变量count用于记录读进程的数目,信号量mutex用于确保count被正确地更新。

int count=0;  //用于记录当前的读者数量
semaphore mutex=1;  //用于保护更新count变量时的互斥
semaphore rw=1;  //用于保证读者和写者互斥地访问文件
writer () {  //写者进程
    while (1){
        P(rw); // 互斥访问共享文件
        Writing;  //写入
        V(rw) ;  //释放共享文件
    }
}
 
reader () {  // 读者进程
    while(1){
        P (mutex) ;  //互斥访问count变量
        if (count==0)  //当第一个读进程读共享文件时
            P(rw);  //阻止写进程写
        count++;  //读者计数器加1
        V (mutex) ;  //释放互斥变量count
        reading;  //读取
        P (mutex) ;  //互斥访问count变量
        count--; //读者计数器减1
        if (count==0)  //当最后一个读进程读完共享文件
            V(rw) ;  //允许写进程写
        V (mutex) ;  //释放互斥变量 count
    }
}

写进程优先
在前面的解决方案中,读进程具有优先权。当一个读进程开始访问数据区时,只要至少有-个读进程正在读,就为读进程保留对这个数据区的控制权,因此,写进程有可能处于饥饿状态。以下方案保证当一个写进程声明想写时,不允许新的读进程访问该数据区。对于写进程,在已有定义的基础上还必须增加下列信号量和变量:

int count = 0;  //用于记录当前的读者数量
semaphore mutex = 1;  //用于保护更新count变量时的互斥
semaphore rw=1;  //用于保证读者和写者互斥地访问文件
semaphore w=1;  //用于实现“写优先”
 
writer(){
    while(1){
        P(w);  //在无写进程请求时进入
        P(rw);  //互斥访问共享文件
        writing;  //写入
        V(rw);  // 释放共享文件
        V(w) ;  //恢复对共享支件的访问
    }
}
 
reader () {  //读者进程
    while (1){
        P (w) ;  // 在无写进程请求时进入
        P (mutex);  // 互斥访问count变量
 
        if (count==0)  //当第一个读进程读共享文件时
            P(rw);  //阻止写进程写
 
        count++;  //读者计数器加1
        V (mutex) ;  //释放互斥变量count
        V(w);  //恢复对共享文件的访问
        reading;  //读取
        P (mutex) ; //互斥访问count变量
        count--;  //读者计数器减1
 
        if (count==0)  //当最后一个读进程读完共享文件
            V(rw);  //允许写进程写
 
        V (mutex);  //释放互斥变量count
    }
}

读者优先和写者优先之间的区别在于:
写者提出了存取共数据区的要求之后,是否允许新的读者继续进入,若允许就是读者优先,若是不允许, 就是写者优先。
在读者优先的情况下,写者可会挨饿,如果后续读者源源不断地进入。在写者优先的情况下,读者可能挨饿,如果有新的写者不断地提出新的要求。