The classic problem of semaphore —— the problem of different priorities for readers and writers

reader writer problem

Read-write mutual exclusion, write-write mutual exclusion, read-read can be concurrent

Reader first

  • When readers and writers are waiting, writers can only write when all readers have finished reading

Semaphore: w=1 (writable), mutex=1 (readable)
Shared variable: rcount=0 (number of readers)

//伪代码
int rcount=0
semaphore w=1,mutex=1
reader(){
    P(mutex);
    rcount++;
    if(rcount==1)
        P(w);//堵塞写者,保证所有读者读完
    V(mutex);
    //以上保证所有读者都可同时读
    //Read()
    P(mutex);
    rcount--;
    if(rcount==0)
        V(w);
    V(mutex);
}

writer(){
    P(w);
    //write()
    V(w);
}

There is a problem, too many readers, starving writers (rcount decreases while also increasing).

Writer first

  • When writers and readers are waiting, readers can only get read permission after all writers have finished writing.

Increase wcount to mark the existence of the writer. If there are readers and writers at the same time, the reader blocks the writer through P(w) during execution, and the writer's wcount mark exists, and the reader is prevented from continuing to join through P(r).

P(x) and V(x) are used to protect atomic operations

int wcount=0,rcount=0;
semaphore w=1,r=1,x=1;
reader(){
    P(r);
    P(x);
    rcount++;
    if(rcount==1)
        P(w);
    V(x);
    V(r);
    //Read()
    P(x);
    rcount--;
    if(rcount==0)
        V(w);
    V(x);
}

writer(){
    P(x);
    wcount++;
    if(wcount==1)
        P(r);
    V(x);
    P(w);
    //Write()
    V(w);
    P(x);
    wcount--;
    if(wcount==0)
        V(r);
    V(x);
}
  • For writing priority issues, I also read some articles, and I think the following is also very good

The classic problem of process synchronization 1 - reader writer problem (writer priority and fair competition)
can refer to, this is the code

semaphore fmutex=1, rdcntmutex=1, wtcntmutex=1, queue=1;
//fmutex --> access to file; rdcntmutex --> access to readcount
//wtcntmutex --> access to writecount
int readcount = 0, writecount = 0;
void reader(){
    while(1){
        wait(queue);
        wait(rdcntmutex);
        if(0 == readcount)wait(fmutex);
        readcount = readcount + 1;
        signal(rdcntmutex);
        signal(queue);
        //Do read operation ...
        wait(rdcntmutex);
        readcount = readcount - 1;
        if(0 == readcount)signal(fmutex);
        signal(rdcntmutex);
    }
}
void writer(){
    while(1){
        wait(wtcntmutex);
        if(0 == writecount)wait(queue);
        writecount = writecount + 1;
        signal(wtcntmutex);
        wait(fmutex);
        //Do write operation ...
        signal(fmutex);
        wait(wtcntmutex);
        writecount = writecount - 1;
        if(0 == writecount)signal(queue);
        signal(wtcntmutex);
    }
}

Add a queued semaphore: queue. The read-write process must queue on this semaphore before accessing the file. By treating the read-write process differently, the priority of the write process can be improved. In addition, add a writecount to record the write access application and the total number of processes that are writing.
Each reading process must apply for a queue semaphore at the beginning, and then give it up before the actual reading operation (so that the writing process can apply for it at any time). queue). And only the first writing process needs to apply for the queue, and then it will be occupied until all the writing processes are completed. It is equivalent to prohibiting the reading process from queuing as long as there is an application from the writing process, which increases the priority of the writing process in disguise. 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325218079&siteId=291194637