基于标准C++实现的信号量类Semaphore

一、缘起

在一个项目中,需要使用到信号量这个东东来同步我的线程,C++已经提供了标准的信号量头文件semaphore.h,那我为什么要重新实现一个呢?因为原来的信号量机制是C style的,信号量一多,整个程序就会非常的混乱,因此我基于C++的mutex和condition_variable来实现了一个自定义的信号量类。

二、实现

1、信号量机制简介

2、实现

/**
 * semaphore类似于一个信号量类,利用mutex和condition_variable来实现
 */
#include 
#include 
#include 
#include 
#include 
#include 

namespace SEM {
    class Semaphore {
    private:
        int _count;                             //等待线程数量
        std::mutex _mutex;                      //互斥锁
        std::condition_variable _condition;     //条件变量
        std::string _name;                      //信号量名字

    public:
        explicit Semaphore(std::string name, int value = 0) :
                _name(std::move(name)), _count(value) {}

        /**
         * 相当于信号量机制里面的P操作.
         * _count大于0(有资源)时,函数会立即返回,否则会阻塞调用此函数的线程.
         */
        void wait() {
            std::unique_lock lock(_mutex);
            //std::cout<<_name+":"<<_count< 0);
            std::unique_lock lock(_mutex);
            //std::cout<<_name+":"<<_count< lock(_mutex);
            if (++_count <= 0) {
                _condition.notify_one();
            }
        }

        /**
         * 如果有线程阻塞,唤醒阻塞的所有线程;否则立即返回.
         */
        void signalAll() {
            std::lock_guard lock(_mutex);
            while (++_count <= 0) {
                _condition.notify_one();
            }
            _count = 0;
        }

        /**
         * 返回这个信号量的名字
         * @return 名字
         */
        std::string name(){
            return _name;
        }

        /**
         * 重载<<,输出信号量的信息
         * @param out 输出流
         * @param sem 信号量
         * @return 输出流
         */
        friend std::ostream &operator<<(std::ostream &out,Semaphore &sem);
    };

    std::ostream &operator<<(std::ostream &out, Semaphore &sem) {
        out<<"Semaphore:"<

 

三、使用

用信号量实现一个简单的生产者消费者模型.

#include 
#include 
#include 
#include 
#include "Semaphore.h"
#include 
#include 

using namespace std;

class Goods{
public:
    explicit Goods(int ii):id(ii){
    }
    int id;
};//产品

SEM::Semaphore *g_sem;

list g_goods;//商品货架

mutex g_mutex;

void producer(){
    default_random_engine e(static_cast(time(0)));
    uniform_int_distribution u(0, 10);
    int i=0;
    while (++i<5) {
        //休眠一段随机时间,代表生产过程
        sleep(u(e));
        //生产
        g_mutex.lock();
        Goods good(u(e));
        g_goods.emplace_back(good);
        cout<<"生产产品:"<signal();
    }
}

void costumer(){
    int i=0;
    while (++i<5) {
        g_sem->wait();//有资源会立即返回,没有资源则会等待
        //消费
        g_mutex.lock();
        Goods good = g_goods.front();
        cout<<"消费产品:"<

 

最后安利一波我自己写的多线程编程模型,非常简单好用!

 

https://github.com/Mannix1994/ThreadPool

你可能感兴趣的:(C++,信号量)