读者-写者问题

问题描述

有读者和写者两组并发进程,共享一个文件,当两个或以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。因此要求:①允许多个读者可以同时对文件执行读操作;②只允许一个写者往文件中写信息;③任一写者在完成写操作之前不允许其他读者或写者工作;④写者执行写操作前,应让已有的读者和写者全部退出。

读优先:

semaphore mutex = 1;//用于保护更新count变量时的互斥
semaphore rw = 1;//用于保证读者和写者互斥地访问文件
int count = 0;//用于记录当前的读者数量
void read(){
    while(1){
        P(mutex);
        if(count == 0)    //当第一个读进程读共享文件时,阻止写进程写
            P(rw);
        ++count;
        V(mutex);
        read_data();
        P(mutex);
        --count;
        if(count == 0)    //当最后一个读进程读完共享文件,允许写进程写
            V(rw);
        V(mutex);
    }
}
void write(){
    while(1){
        P(rw);
        write_data();
        V(rw);
    }
}

在上面的算法中,读进程是优先的,也就是说,当存在读进程时,写操作将被延迟,并且只要有一个读进程活跃,随后而来的读进程都将被允许访问文件。这样的方式下,会导致写进程可能长时间等待,且存在写进程“饿死”的情况。

写优先

如果希望写进程优先,即当有读进程正在读共享文件时,有写进程请求访问,这时应禁止后续读进程的请求,等待到已在共享文件的读进程执行完毕则立即让写进程执行,只有在无写进程执行的情况下才允许读进程再次运行。为此,增加一个信号量并且在上面的程序中 writer()和reader()函数中各增加一对PV操作,就可以得到写进程优先的解决程序。

semaphore read_mutex = 1;
semaphore write_mutex = 1;
semaphore rw = 1;
semaphore w = 1;    //用于实现“写优先”
int read_count = 0;
int write_count = 0;
void read() {
       while (1) {
              P(w);    //在无写进程请求时进入
              P(read_mutex);
              if (read_count == 0)
                     P(rw);
              ++read_count;
              V(read_mutex);
              V(w);    //恢复对共享文件的访问    
              read_data();
              P(read_mutex);
              --read_count;
              if (read_count == 0)
                     V(rw);
              V(read_mutex);
       }
}
void write() {
       while (1) {
              P(write_mutex);
              if (write_count == 0)
                     P(w);    //请求写
              write_count++;
              V(write_mutex);
              P(rw);
              write_data();
              V(rw);
              P(write_mutex);
              --write_count;
              if (write_count == 0)
                     V(w);
              V(write_count);
       }
}

公平竞争:

semaphore mutex = 1;
semaphore rw = 1;
semaphore key = 1;    //用于实现“公平竞争”
int count = 0;
void read(){
    while(1){
        P(key);    //在无写进程请求时进入
        P(mutex);
        if(count == 0)
            P(rw);
        ++count;
        V(mutex);
        V(key);    //恢复对共享文件的访问    
        read_data();
        P(mutex);
        --count;
        if(count == 0)
            V(rw);
        V(mutex);
    }
}
void write(){
    while(1){
        P(key);    //请求写
        P(rw);
        write_data();
        V(rw);
        V(key);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值