线程的同步机制

WebServer线程同步机制

线程的同步机制有哪些?

临界区

临界区是一段独占某些共享资源访问的代码,在任意时刻都只允许一个线程对这份共享资源进行访问(利用互斥锁实现)。如果有多个线程试图访问此共享资源,那么在有一个线程进入后其他所有试图访问此临界区的线程都将被挂起,一直持续到已经进入临界区的线程离开。

临界区被释放后,线程解锁,其他线程继续抢占,以此来达到用原子操作共享资源的目的。

PS:私人浴室(没有管理员)只有一间淋浴房,我想洗澡,我时不时来看下淋浴房空了没,空了我就去洗。

互斥量(互斥锁)

和临界区大差不差,它强调的是资源之间的互斥访问:每个线程在对共享资源进行操作时,必须先尝试加锁,只有加锁成功的线程才能访问此共享资源,等线程操作结束后就解锁

可以用于不同线程间的线程同步

PS:公共浴室(有管理员)只有一间淋浴房,我想洗澡,问了下管理员,有空的淋浴房么,如果有,管理员就让我洗,否则管理员就让我先去休息室睡一觉,等有空的淋浴房了叫醒我去洗澡。

条件变量

与互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止通常条件变量和互斥锁同时使用

条件变量分为两部分: 条件和变量。条件本身是由互斥量保护的。线程在改变条件状态前先要锁住互斥量。条件变量使我们可以睡眠等待某种条件出现。

条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待“条件变量的条件成立”而挂起;另一个线程使“条件成立”(给出条件成立信号)。条件的检测是在互斥锁的保护下进行的。如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。如果另一个线程改变了条件,它发信号给关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步

信号量

信号量用于限制对临界资源的访问数量,保证了消费数量不会大于生产数量

PS:公共浴室(有管理员)有N间(资源数量限制)淋浴房,我想洗澡,问了下管理员,有空的淋浴房么,如果有,管理员就让我洗,否则管理员就让我先去休息室睡一觉,等有空的淋浴房了叫醒我去洗澡。

事件

触发重置事件对象,那么等待的所有线程中将只有一个线程能唤醒,并同时自动的将此事件对象设置为无信号的;它能够确保一个线程独占对一个资源的访问

和互斥量的区别在于多了一个前置条件判定

PS:公共浴室(有管理员)只有一间淋浴房,我想洗澡,问了下管理员,有空的淋浴房么,如果淋浴房没人洗而且打扫完了(等待的事件),管理员就让我洗,否则管理员就让我先去休息室睡一觉,等没人洗而且打扫完了叫醒我去洗澡

线程同步机制的封装代码:

//locker.h
#ifndef LOCKER_H
#define LOCKER_H

#include<pthread.h>
#include<exception>
#include<semaphore.h>

//线程同步机制封装

//互斥锁类
class locker{
public:
    locker(){
        if(pthread_mutex_init(&m_mutex,NULL)!=0){
            throw std::exception();//抛出异常
        }
    }

    ~locker(){
        pthread_mutex_destroy(&m_mutex);
    }

    //上锁
    bool lock(){
        return pthread_mutex_lock(&m_mutex)==0;
    }

    //解锁
    bool unlock(){
        return pthread_mutex_unlock(&m_mutex)==0;
    }

    //获取成员互斥量
    pthread_mutex_t* get(){
        return &m_mutex;
    }
private:
    pthread_mutex_t m_mutex;//互斥锁
};

//条件变量类
class cond{
public:
    cond(){
        if(pthread_cond_init(&m_cond,NULL)!=0){
            pthread_mutex_destroy(&m_mutex);
            throw std::exception();
        }
    }

    ~cond(){
        pthread_cond_destroy(&m_cond);;
    }

    bool wait(pthread_mutex_t* mutex){
        pthread_mutex_lock(&m_mutex);
        return pthread_cond_wait(&m_cond,mutex)==0;
        pthread_mutex_unlock(&m_mutex);
    }

    //超时时间
    bool timedwait(pthread_mutex_t* mutex,struct timespec t){
        pthread_mutex_lock(&m_mutex);
        return pthread_cond_timedwait(&m_cond,mutex,&t)==0; 
        pthread_mutex_unlock(&m_mutex);
    }

    //增加条件变量  让一个或者多个线程唤醒
    bool signal(){
        return pthread_cond_signal(&m_cond)==0;
    }

    //将所有的线程都唤醒
    bool broadcast(){
        return pthread_cond_broadcast(&m_cond)==0;
    }
private:
    static pthread_mutex_t m_mutex;
    pthread_cond_t m_cond;
};

//信号量类
class sem{
public:
    sem(){
        if(sem_init(&m_sem,0,0)!=0){
            throw std::exception();
        }
    }

    sem(int num){
        if(sem_init(&m_sem,0,num)!=0){
            throw std::exception();
        }
    }

    ~sem(){
        sem_destroy(&m_sem);
    }

    //等待信号量
    bool wait(){
        return sem_wait(&m_sem)==0;
    }

    //增加信号量
    bool post(){
        return sem_post(&m_sem)==0;
    }
private:
    sem_t m_sem;
};

#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值