【问题标题】:How do I limit the concurrent number of readers in a first readers writers problem?如何限制第一个读者作者问题中的并发读者数量?
【发布时间】:2026-01-04 19:20:02
【问题描述】:

我想了解如何实现某种形式的并发来限制读者的数量。

void *reader(void *rno)
{   
    // Reader acquire the lock before modifying numreader
    pthread_mutex_lock(&mutex);
    numreader++;
    if(numreader == 1) {
        sem_wait(&wrt); 
    }
    pthread_mutex_unlock(&mutex);
    // Reading Section
    printf("Reader %d: read cnt as %d\n",*((int *)rno),cnt);

    // Reader acquire the lock before modifying numreader
    pthread_mutex_lock(&mutex);
    numreader--;
    if(numreader == 0) {
        sem_post(&wrt);
    }
    pthread_mutex_unlock(&mutex);
}

我试过这个,虽然这只是让所有读者都可以运行并在之后调用编写器,但我想了解如何一次调用有限数量的读者,然后允许编写器运行。

wrt 是二进制信号量,但如果是计数信号量初始化到极限,这是否有助于实现目标?

【问题讨论】:

  • 如果wrt是一个初始化到极限的计数信号量,它应该可以帮助你实现目标,是的。事实上,这就是你所需要的,如果我没记错的话,实际上有部分代码需要删除。由于使用numreader,当前代码不允许多个阅读器同时阅读。我会删除所有与numreader 相关的代码,只留下sem_wait、阅读部分和sem_post。除非我错过了什么。

标签: c computer-science semaphore


【解决方案1】:

是的,将计数设置为最大阅读器计数的计数信号量可以解决这个问题。下面是一小段 Java 代码,你可以运行来理解。

import java.util.ArrayList;
import java.util.List;

import static java.lang.System.currentTimeMillis;

class CountingSemaphore {
    private final int maxCount;
    private int signals = 0;

    public CountingSemaphore(int maxCount) {
        this.maxCount = maxCount;
    }

    public synchronized void take() throws InterruptedException {
        while (signals==this.maxCount) wait();
        this.signals++;
        this.notify();
    }

    public synchronized void release() throws InterruptedException{
        while(this.signals == 0) wait();
        this.signals--;
        this.notify();
    }

    public synchronized int getThreadCount(){
        return signals;
    }

}
class Reader{
    private final int id;

    public Reader(int id) {
        this.id = id;
    }

    public void read(CountingSemaphore semaphore) throws InterruptedException {
        semaphore.take();

        System.out.printf("Reader %d is reading. Reader count is %d%n", id, semaphore.getThreadCount());
        semaphore.release();
    }
}

public class ConcurrentReaderTest {
    public static void main(String[] args){
        CountingSemaphore countingSemaphore = new CountingSemaphore(5);
        List<Thread> readerThreads = new ArrayList<>();

        for(int i=0;i<10;i++){
            Reader reader = new Reader(i);
            readerThreads.add(new Thread(()-> {
                try {
                    reader.read(countingSemaphore);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }));
        }
        readerThreads.stream().forEach(r->r.start());
        long startTime = currentTimeMillis();
        readerThreads.stream().forEach(r->r.run());
        System.out.println("time taken: "+ String.valueOf(currentTimeMillis()-startTime));


    }
}

【讨论】:

    最近更新 更多