linux线程同步

概念

同步:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避免饥饿问
题,叫做同步
竞态条件:因为时序问题,而导致程序异常,我们称之为竞态条件。
条件变量:当一个线程互斥地访问某个变量时,它可能发现在其它线程改变状态之前,它什么也做不了。

条件变量函数

初始化

int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict 
attr);

参数:
cond:要初始化的条件变量
attr:NULL

销毁

int pthread_cond_destroy(pthread_cond_t *cond) 

等待条件满足

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex); 

参数:
cond:要在这个条件变量上等待
mutex:互斥量

唤醒等待

int pthread_cond_broadcast(pthread_cond_t *cond); 
int pthread_cond_signal(pthread_cond_t *cond); 

signal:唤醒一个在该条件等待的线程
broadcast:唤醒所以在该条件等待的线程

为什么 pthread_cond_wait 需要互斥量?

条件等待是线程间同步的一种手段,如果只有一个线程,条件不满足,一直等下去都不会满足,所以必须要有一个线程通过某些操作,改变共享变量,使原先不满足的条件变得满足,并且友好的通知等待在条件 变量上的线程。
条件不会无缘无故的突然变得满足了,必然会牵扯到共享数据的变化。所以一定要用互斥锁来保护。没有 互斥锁就无法安全的获取和修改共享数据。

正确使用

pthread_mutex_lock(&mutex); 
while (条件为假) 
pthread_cond_wait(cond, mutex); 
修改条件 
pthread_mutex_unlock(&mutex); 

阻塞队列

#pragma once
#include<iostream>
#include<queue>
#include<pthread.h>
#include<cstdlib>
#include<ctime>
#include<unistd.h>
using namespace std;

#define SIZE 10

template<class T>
class blockQueue
{
public:
    blockQueue(int cap = SIZE):_cap(cap)
    {
        pthread_mutex_init(&_conMutex,nullptr);
        pthread_mutex_init(&_proMutex,nullptr);
        pthread_cond_init(&_conCond,nullptr);
        pthread_cond_init(&_proCond,nullptr);
    }
    //生产者
    void push(const T& val)
    {
        //生产者加锁
        proLock();
        //  判断同步条件
        while(isFull())
        {
            //等待条件满足
            waitofPro();
        }

        //生成数据
        creatVal(val);

        //解锁
        prounLock();

        //唤起消费者
        wakeupCon();
        
    }

    T pop()
    {
        //消费者加锁
        conLock();
        //  判断同步条件
        while(isEmpty())
        {
            //等待条件满足
            waitofCon();
        }

        //消费数据
        T tmp = getVal();

        //解锁
        conunLock();

        //唤起生产者
        wakeupPro();

        return tmp;
    }

    ~blockQueue()
    {
        pthread_mutex_destroy(&_conMutex);
        pthread_mutex_destroy(&_proMutex);

        pthread_cond_destroy(&_conCond);
        pthread_cond_destroy(&_proCond);
    }

private:

    //消费者加锁
    void conLock()
    {
        pthread_mutex_lock(&_conMutex);
    }
    //消费者解锁
    void conunLock()
    {
        pthread_mutex_unlock(&_conMutex);
    }

    bool isEmpty()
    {
        return _bq.empty();
    }
    //等待条件满足
    void waitofCon()
    {
        pthread_cond_wait(&_conCond,&_conMutex);
    }

    //唤醒生产者
    void wakeupPro()
    {
        pthread_cond_signal(&_proCond);
    }

    T getVal()
    {
        T tmp = _bq.front();
        _bq.pop();
        return tmp;
    } 

    //生产者加锁
    void proLock()
    {
        pthread_mutex_lock(&_proMutex);
    }
    //生产者解锁
    void prounLock()
    {
        pthread_mutex_unlock(&_proMutex);
    }

    bool isFull()
    {
        return _bq.size()==_cap;
    }

    //等待条件满足
    void waitofPro()
    {
        pthread_cond_wait(&_proCond,&_proMutex);
    }

    void creatVal(const T& val)
    {
        _bq.push(val);
    }

    //唤醒消费者
    void wakeupCon()
    {
        pthread_cond_signal(&_conCond);
    }




    queue<T> _bq; //阻塞队列
    int _cap; // 大小
    pthread_mutex_t _conMutex; // 消费者锁
    pthread_mutex_t _proMutex; // 生成者锁
    pthread_cond_t _conCond;  // 消费者同步条件
    pthread_cond_t _proCond;  // 生成者同步条件
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值