【Linux】---互斥与同步、死锁与饥饿、实现生产者消费者模型、常见锁类型

梳理前言

进程线程间的互斥相关背景概念:

  1. 临界资源:多线程执行流共享的资源就叫做临界资源
  2. 临界区:每个线程内部,访问临界资源的代码,就叫做临界区
  3. 互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用。
  4. 原子性:不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成。
  5. 死锁:两个或两个以上的进程(LWP)都在等待互相释放自己的资源,导致进程都不能继续执行的情形,称为死锁。
  6. 竞争条件:多个线程或进程在读写一个共享资源时的结果,依赖于他们执行的相对时间,这种情况叫做竞争。
  7. 饥饿:由于竞争条件不平等,与其他进程或线程竞争访问共享资源运行期间,被调度器无限忽视,无法访问共享资源的情况,称为饥饿。

梳理:

互斥:为了保证多个线程或进程访问同一份资源时,保证不产生数据二义性,用原子性的操作,去限制一部分线程的访问。

同步:为了保证各个线程之间互斥访问共享资源的顺序合理且高效,用条件变量和信号量(原子性操作)去安排访问顺序。

死锁:详情看上述概念,另外不是一定要两个以上的进程或线程才会死锁,一个也可以。看下面这种情形。

互斥量(锁)本身也是一种共享资源,如果一个线程中,申请了一把锁,在没有解锁的情况下,它又去申请这把锁,也会死锁,也就是自己等自己释放锁的情形。

饥饿:线程的创建时间有先后,调度器调度自然也有先后,如果我们不进行同步处理,先创建的线程很有可能就会一个人使用了共享资源,其他线程处于饥饿状态,这是不合理的。

在这里插入图片描述

互斥与同步

互斥量与条件变量

互斥量通常与条件变量一起使用,达到互斥与同步的效果。

生产者与消费者模型就是一个很好的例子。模拟实现一个

当然,如果只有一个生产者,那它也不需要和其他生产者竞争。

只有一个消费者,它也不需要和其他消费者竞争。

用队列来模拟上述商品为满或者为空的场景,同时有多个消费者和生产者。

#pragma once
#include <iostream>
#include <queue>
#include <pthread.h>
#include<unistd.h>

class mask
{
   
  public:
    int left;
    int right;
  public:
    mask(int a=0,int b=0)
    {
   
      left=a;
      right=b;
    }

    int add()
    {
   
      int c=left+right;
      std::cout<<left<<"+"<<right<<"="<<c<<std::endl;
      return c;
    }
};

template<class T>
class block_queue
{
   
  private:
    std::queue<T> q;
    int cap;
    pthread_mutex_t lock;
    pthread_cond_t empty;
    pthread_cond_t full;
    
    void lock_queue()
    {
   
      pthread_mutex_lock(&lock);
    }

    void unlock_queue()
    {
   
      pthread_mutex_unlock(&lock);
    }
    
    bool Is_full()
    {
   
      return q.size
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值