• 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
  • 相关阅读:
    仅三天,我用 GPT-4 生成了性能全网第一的 Golang Worker Pool,轻松打败 GitHub 万星项目
    【图像检测】基于计算机视觉实现手位置检测附matlab代码
    Kubernetes: kube-apiserver 之认证
    Dockerfile讲解
    使用Tomcat部署SpringBoot项目
    Fiddler - The system proxy was changed. Click to reenable capturing.
    Qt实现编辑框失去焦点隐藏功能
    IDEA中DEBUG调试代码F7、F8、F9
    Aws Nat Gateway
    Recurrence relation
  • 原文地址:https://blog.csdn.net/zjq_love/article/details/128002778