• POSIX信号量


    概念

    信号量是一个计数器,用来描述临界资源数量的计数器。
    每个执行流要进入临界资源时,要先申请信号量,出临界资源时,要释放信号量。
    在这里插入图片描述
    在这里插入图片描述
    信号量的PV操作
    P操作:申请信号量,进入临界资源前,会申请信号量,x–,如果x为0时,则会堵塞等待
    V操作:释放信号量,出临界资源后,会释放信号量,x++

    信号量函数

    初始化信号量

    int sem_init(sem_t *sem, int pshared, unsigned int value); 
    
    • 1

    参数:
    sem: 输出型参数,信号量的标号
    pshared:0表示线程间共享,非零表示进程间共享
    value:信号量初始值 即x的值

    销毁信号量

    int sem_destroy(sem_t *sem);
    
    • 1

    等待信号量
    功能:等待信号量,会将信号量的值减1

    int sem_wait(sem_t *sem); //P操作 
    
    • 1

    发布信号量
    功能:发布信号量,表示资源使用完毕,可以归还资源了。将信号量值加1。

    int sem_post(sem_t *sem);//V操作
    
    • 1

    基于环形队列的生产消费模型

    #pragma once
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    
    using namespace std;
    template<class T>
    class ringqueue
    {
    public:
        ringqueue(int cap=10):_cap(cap)
        {
            _rq.resize(cap);
            sem_init(&_room,0,cap);
            sem_init(&_data,0,0);
            pthread_mutex_init(&_mutexR,nullptr);
            pthread_mutex_init(&_mutexD,nullptr);
            _rIndex=_dIndex=0;
        }
        ~ringqueue()
        {
            sem_destroy(&_room);
            sem_destroy(&_data);
            pthread_mutex_destroy(&_mutexR);
            pthread_mutex_destroy(&_mutexD);
        }
    
        void push(const T& val)
        {
            //等待信号
            sem_wait(&_room);
    
            pthread_mutex_lock(&_mutexR);
    
            _rq[_rIndex]=val;
    
            _rIndex++;
            _rIndex%=_cap;
            pthread_mutex_unlock(&_mutexR);
            //发送信号
            sem_post(&_data);
        }
    
        T pop()
        {
            //等待信号
            sem_wait(&_data);
    
            pthread_mutex_lock(&_mutexD);
            T tmp = _rq[_dIndex];
            _dIndex++;
            _dIndex%=_cap;
    
            pthread_mutex_unlock(&_mutexD);
            //发送信号
            sem_post(&_room);
            return tmp;
        }
    
    
    private:
    
    
    private:
        vector<T> _rq ;//循环队列
        int _cap; // 大小
        int _rIndex; //空间对应的下标
        int _dIndex; //数据对应的下标
        sem_t _room; //剩余空间 
        sem_t _data; //已有数据
        pthread_mutex_t _mutexR; //空间锁
        pthread_mutex_t _mutexD; //数据锁
    
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
  • 相关阅读:
    编译链接(Compile Link)
    第一个Vue程序
    mTD-SCDMA与TD-LTE双网络垂直切换matlab仿真
    酷开科技 | 酷开系统沉浸式大屏游戏更解压!
    普通人想要通过互联网来赚钱,无非就是在这些平台上面来下功夫
    前端uniapp请求真是案例(带源码)
    HIVE-17824,删除hdfs分区信息,清理metastore元数据
    牛客剑指offer刷题算法篇
    记录IFA2023上的中国8K摄像机
    【Linux operation 38】解决Linux 端口被占用
  • 原文地址:https://blog.csdn.net/zjq_love/article/details/128002778