gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 18:38:19 34 4
gpt4 key购买 nike

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

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

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

A similar question 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都是非阻塞的,如果compare和exchange操作是非阻塞的(可以勾选)。

关于c++ - C++11 中的非阻塞信号量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42269611/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com