ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++实现信号量

2021-07-06 23:04:35  阅读:254  来源: 互联网

标签:实现 阻塞 C++ 信号量 线程 Semaphore iCount wait


背景
实现
代码toc

背景

信号量与条件变量差异对比

  • 信号量存在一个计数,可以反映出当前阻塞在wait上的线程数(值小于0),或下次wait不会阻塞的线程数;条件变量没有相应计数
  • 信号量仅能递增或递减计数,信号量每次递增只能唤醒一个阻塞线程;条件变量存在广播操作,能一次性唤醒所有阻塞线程
  • 信号量计数可以被初始化为大于0的数n,代表可访问资源个数,在后续访问时wait时,n个线程均不会阻塞,可同时访问资源;条件变量初始化后,执行wait的线程将全部阻塞,直到收到通知
  • 信号量递增一次,便会多一个wait不阻塞的线程数(不存在阻塞线程时);对于条件变量,当没有线程阻塞在wait时,发出的唤醒信号将被丢弃,导致先发出唤醒信号,随后wait将仍被阻塞,即所谓的唤醒丢失
  • 信号量不存在虚假唤醒问题;条件变量存在虚假唤醒
  • 信号量可单独使用;条件变量必须需配合mutex一起使用

C++标准库仅有条件变量,而没有信号量,下面实现一个跨平台信号量

实现

信号量最基本的操作有三个

  • 初始化决定了wait后可立即执行线程数
  • 递减操作SemWait,该操作使信号量减1,如果减1后变为负数,线程会阻塞在SemWait上,否则继续执行
  • 递增操作SemSignal,该操作使信号量加1,如果加1后大于等于0,阻塞在SemWait上的线程被唤醒

代码

#pragma once
#include <mutex>
#include <condition_variable>

class Semaphore final{
public:
    explicit Semaphore(int iCount = 0);
    ~Semaphore();

    void Signal();
    void Wait();
    int GetValue();

    Semaphore(const Semaphore& rhs) = delete;
    Semaphore(Semaphore&& rhs) = delete;
    Semaphore& operator=(const Semaphore& rhs) = delete;
    Semaphore& operator=(Semaphore&& rhs) = delete;

private:
    std::mutex m_mLock;
    std::condition_variable m_cConditionVariable;
    int m_iCount;
};
#include "Semaphore.h"

Semaphore::Semaphore(int iCount) : m_iCount(iCount){
}

Semaphore::~Semaphore(){
}

void Semaphore::Signal(){
    std::unique_lock<std::mutex> lock(m_mLock);
    if(++m_iCount >= 0){
        m_cConditionVariable.notify_one();
    }
}

void Semaphore::Wait(){
    std::unique_lock<std::mutex> lock(m_mLock);
    --m_iCount;
    m_cConditionVariable.wait(lock, [this] { return m_iCount >= 0; });
}

int Semaphore::GetValue(){
    std::unique_lock<std::mutex> lock(m_mLock);
    return m_iCount;
}


来自为知笔记(Wiz)

标签:实现,阻塞,C++,信号量,线程,Semaphore,iCount,wait
来源: https://www.cnblogs.com/Keeping-Fit/p/14979384.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有