将Linux中信号量转为C++类

#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_;
    };
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值