同步与互斥

Linux

线程共享了进程的资源(地址空间, 页表等), 多个线程同时访问同一个资源就可能产生问题:数据竞争

  • 临界资源: 多个线程共享的资源
  • 临界区: 访问临界资源的区域
  • 互斥: 任何时刻, 只有一个执行流能进入临界区
  • 同步: 以一定顺序访问临界资源
  • 原子性: 要么完成, 玩么未完成

  • 死锁:一组进程占有资源,不释放 + 互相申请, 导致永久等待的状态
  • 互斥锁:访问机制, 保证任何时刻, 只有一个线程能访问临界资源
  • 自旋锁:访问机制, 申请锁失败会一直检测锁的状态
  • 读写锁:读可并发, 写会独占资源. 一般适合读取数据次数 > 写数据的次数
  • 悲观锁:读取数据先加锁, 其它线程访问数据时会被阻塞
  • 乐观锁:读取数据时不加锁,更新数据时会比较数据是否被修改(被修改:重试或放弃等)

死锁

产生条件

  • 互斥条件:一个资源每次只能被一个执行流使用
  • 请求与保持条件:一个执行流因请求资源而阻塞时,对已获得的资源保持不放
  • 不剥夺条件:一个执行流已获得的资源,在末使用完之前,不能强行剥夺
  • 循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系

避免死锁

  • 破坏死锁的四个必要条件
  • 加锁顺序一致
  • 避免锁未释放的场景
  • 资源一次性分配

互斥锁

操作:

  • 头文件:<pthread.h>
  • int pthread_mutex_init(pthread_mutex_t *mutex)函数进行初始化
  • int pthread_mutex_lock(pthread_mutex_t *mutex)进行加锁(阻塞式)
  • int pthread_mutex_trylock(pthread_mutex_t *mutex)(非阻塞式)
  • int pthread_mutex_unlock(pthread_mutex_t *mutex)解锁
  • int pthread_mutex_destroy(pthread_mutex_t *mutex)销毁

原理:

  • lock:1.将0放入寄存器%al中  2. 把寄存器%al的值与内存中mutex的值做交换 3.如果al寄存器的内容>0 , 说明申请锁成功, 就返回0, 否则申请失败, 就挂起等待
  • unlock: 把1给内存中的mutex

条件变量

  • 概念: 是用于线程通信同步的机制, 通常与锁一起使用
  • 功能: 阻塞等待某种条件, 条件满足后继续执行(A线程等待B线程完成某种任务后,才向后执行)
  • 与锁一起使用: A线程在不满足条件时会释放锁, 直到条件就绪会重新获取锁然后继续执行

操作

头文件: <pthread.h>

pthread_cond_init

函数原型:int pthread_cond_init(pthread_cond_t *restrict cond, 
                      const pthread_condattr_t *restrict attr);
功能:初始化条件变量
参数:cond 是指向条件变量对象的指针,attr 是一个指向线程属性对象的指针,可以为 NULL。
返回值:调用成功返回0,失败返回错误码

pthread_cond_destroy

函数原型:int pthread_cond_destroy(pthread_cond_t *cond);
功能:销毁条件变量
参数:cond 是指向已初始化的条件变量对象的指针。
返回值:调用成功返回0,失败返回错误码。

pthread_cond_wait

函数原型:int pthread_cond_wait(pthread_cond_t *restrict cond,  
                            pthread_mutex_t *restrict mutex);
功能:等待条件变量,并在收到信号或广播时解除阻塞
参数:cond 是指向条件变量对象的指针,mutex 是与条件变量相关联的互斥锁。
返回值:调用成功返回0,失败返回错误码。
 
规范: 在while()中等待-->保证条件就绪的时候再被唤醒

pthread_cond_signal

功能:当条件满足时用来唤醒等待在条件变量上的一个线程。
函数原型:int pthread_cond_signal(pthread_cond_t *cond);
功能:唤醒一个等待在条件变量上的线程
参数:cond 是指向条件变量对象的指针。
返回值:调用成功返回0,失败返回错误码

pthread_cond_broadcast

函数原型:int pthread_cond_broadcast(pthread_cond_t *cond);
功能:唤醒所有等待在条件变量上的线程
参数:cond 是指向条件变量对象的指针。
返回值:调用成功返回0,失败返回错误码。

信号量

  • 概念: 一种软件资源(本质时计数器 ,对临界资源的预定机制)
  • 意义: 不用进入临界区就能知到资源情况(减少临界区内部的判断)

操作

头文件: <semaphore.h> <pthread.h>

sem_init

函数原型:int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:初始化一个未命名的信号量
参数:
    sem 是指向信号量对象的指针,
    pshared 用于指示信号量是在进程间共享还是线程间共享,
    value 是信号量的初始值。
返回值:调用成功返回0,失败返回-1

sem_destory

函数原型:int sem_destroy(sem_t *sem);
功能:销毁一个未命名的信号量
参数:sem 是指向已初始化的信号量对象的指针
返回值:调用成功返回0,失败返回-1

sem_wait(申请信号量)

函数原型:int sem_wait(sem_t *sem);
功能:等待信号量,如果信号量的值大于0,将其减1;否则将线程阻塞,直到信号量的值大于0
参数:sem 是指向信号量对象的指针
返回值:调用成功返回0,失败返回-1

sem_post(释放信号量)

函数原型:int sem_post(sem_t *sem);
功能:释放信号量,将信号量的值加1,唤醒等待该信号量的线程
参数:sem 是指向信号量对象的指针
返回值:调用成功返回0,失败返回-1
  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值