【问题标题】:linux c++ create semaphore with a max valuelinux c ++创建具有最大值的信号量
【发布时间】:2014-04-07 05:44:43
【问题描述】:

我想创建一个队列来存储我的任务,我希望它是一个缓冲队列,并且我想使用信号量来保持它的线程安全,因为我使用多个线程来执行从任务队列..当队列的大小小于buffer_size(我定义的变量)时,add_task线程会将新任务推送到任务队列,当队列满时,任务线程会被阻塞,所以我需要最大值等于 buffer_size 的信号量。

我知道在windows api中有CreateSemophore,我可以在其中设置信号量的最大值:

CreateSemaphore( 
        NULL,           // default security attributes
        MAX_SEM_COUNT,  // initial count
        MAX_SEM_COUNT,  // maximum count
        NULL);          // unnamed semaphore

但是在linux中,我只能得到sem_init函数:

int sem_init (sem_t *sem, int pshared, unsigned int value)

我只能设置初始值,但最大值据说是int的范围..

所以我的问题是如何在 Linux 上的 C++ 中创建具有最大值的信号量?

【问题讨论】:

    标签: c++ linux multithreading


    【解决方案1】:

    围绕这个明显的限制进行设计 - 使用两个信号量(和一个互斥体)。这是有界生产者-消费者队列的“经典”模式。

    将一个“spaceRemaining”初始化为 buffer_size - 生产者在获取互斥体并推送数据之前等待它,消费者在弹出数据并释放互斥体后发出信号。

    将另一个“entryCount”初始化为零 - 生产者在推送数据并释放互斥体后发出信号,消费者在获取互斥体并弹出数据之前等待它。

    这样就不需要对信号量做任何限制了,伪代码:

    Sema spaceRemaining(buffer_size);
    Sema entryCount(0);
    ..
    ..
    void *Producer(Data data){
      spaceRemaining.wait();
      mutex.acquire();
      queue.push(data);
      mutex.release();
      entryCount.signal();
    };
    
    Data Consumer(){
      entryCount.wait();
      mutex.acquire();
      Data localData=queue.pop();
      mutex.release(); 
      spaceRemaining.signal();
      return localData;
    };
    

    【讨论】:

    • 这会导致死锁情况吗?
    • 不,它不能。这是一种已经使用了几十年的标准模式。见 Dijkstra。
    • 所有任务完成后如何让生产者和消费者线程退出?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多