C ++ 11中的非阻塞信号量?

时间:2017-02-16 09:19:42

标签: c++ multithreading c++11

本网站上的一些问题涉及C ++ 11中引入的多线程支持中缺少信号量对象。很多人建议implementing semaphores using mutexes or condition variables or a combination of both

但是,这些方法都不允许增加和减少信号量,同时保证调用线程不被阻塞,因为通常必须在读取信号量值之前获取锁定。例如,POSIX信号量具有函数sem_post()sem_trywait(),两者都是非阻塞函数。

是否可以仅使用C ++ 11多线程支持实现非阻塞信号量?或者我是否一定要为此使用依赖于操作系统的库?如果是这样,为什么C ++ 11修订版不包含信号量对象?

similar question未在3年内得到答复。 (注意:我相信我要问的问题要广泛得多,除了生产者/消费者之外,还有一些非阻塞信号量对象的其他用途。如果有人认为我的问题是重复的,请告诉我如何我可以回想一下旧问题,因为这仍然是一个悬而未决的问题。)

1 个答案:

答案 0 :(得分:3)

我没有看到实现信号量的问题。使用C ++ 11原子和互斥体应该是可能的。

class Semaphore
{
private:
    std::atomic<int> count_;

public:
    Semaphore() :
        count_(0) // Initialized as locked.
    {

    }
    void notify() {
        count_++;
    }

    void wait() {
        while(!try_wait()) {
            //Spin Locking
        }
    }

    bool try_wait() {
        int count = count_;
        if(count) {
            return count_.compare_exchange_strong(count, count - 1);
        } else {
            return false;
        }
    }
};

以下是一个用法示例:

#include <iostream>
#include "Semaphore.hpp"
#include <thread>
#include <vector>

Semaphore sem;
int counter;

void run(int threadIdx) {
    while(!sem.try_wait()) {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }
    //Alternative use wait
    //sem.wait()
    std::cout << "Thread " << threadIdx << " enter critical section" << std::endl;
    counter++;
    std::cout << "Thread " << threadIdx << " incresed counter to " << counter << std::endl;

    // Do work;
    std::this_thread::sleep_for(std::chrono::milliseconds(30));

    std::cout << "Thread " << threadIdx << " leave critical section" << std::endl;
    sem.notify();
}
int main() {
    std::vector<std::thread> threads;
    for(int i = 0; i < 15; i++) {
        threads.push_back(std::thread(run, i));
    }

    sem.notify();


    for(auto& t : threads) {
        t.join();
    }
    std::cout << "Terminate main." << std::endl;
    return 0;
}

当然,等待是阻止操作。但是如果比较和交换操作是非阻塞的(可以检查),则notify和try_wait都是非阻塞的。

相关问题