#pragma once
#include <errno.h>
#include <semaphore.h>
namespace Yanhai {
class Semaphore final {
public:
// 构造函数,初始化信号量
Semaphore(Semaphore&&) = delete;
Semaphore(const Semaphore&) = delete;
Semaphore(unsigned int Value = 0) {
if (sem_init(&Sem_, 0, Value) != 0) {
throw std::runtime_error("Failed to initialize semaphore.");
}
}
// 析构函数,销毁信号量
~Semaphore() {
sem_destroy(&Sem_);
}
// 重载=操作符
Semaphore& operator=(const Semaphore&) = delete;
Semaphore& operator=(Semaphore&&) = delete;
// 等待信号量,无限期等待
void Wait() {
int Result;
while (true) {
Result = sem_wait(&Sem_);
if (0 == Result) {
return;
}
else if (EINTR == errno) {
continue; // Interrupted by signal, retry
}
else {
throw std::runtime_error("Failed to wait for semaphore");
}
}
}
// 等待信号量,支持毫秒级别的超时
bool WaitFor(int Milliseconds) {
struct timespec Timespec;
if (-1 == clock_gettime(CLOCK_REALTIME, &Timespec)) {
throw std::runtime_error("Failed to get current time");
}
Timespec.tv_sec += Milliseconds / 1000;
Timespec.tv_nsec += (Milliseconds % 1000) * 1000000;
if (Timespec.tv_nsec >= 1000000000) {
Timespec.tv_sec += 1;
Timespec.tv_nsec -= 1000000000;
}
int Result;
while (true) {
Result = sem_timedwait(&Sem_, &Timespec);
if (0 == Result) {
return true;
}
else if (EINTR == errno) {
continue; // Interrupted by signal, retry
}
else if (ETIMEDOUT == errno) {
return false; // Timeout
}
else {
throw std::runtime_error("Failed to wait for semaphore");
}
}
}
// 清理信号量
void Flush(int Number = -1) {
if (-1 == Number) {
while (sem_trywait(&Sem_) == 0);
}
else {
/* 这里的目的是为了减少 Number 个资源 */
while (Number-- && (sem_trywait(&Sem_) == 0));
}
}
// 释放信号量
void Post() {
if (sem_post(&Sem_) != 0) {
throw std::runtime_error("Failed to post semaphore.");
}
}
private:
sem_t Sem_;
};
}
将Linux中信号量转为C++类
最新推荐文章于 2024-07-14 02:05:00 发布