线程的同步机制

线程怎么实现同步

前文有提到,一个进程中的各个线程都有共享的资源而且是完全开放的,那么在进程运行中会出现多个线程访问同一个公共资源的问题。

这种现象我们称之为线程之间产生了资源竞争,这种竞争会导致程序异常甚至崩溃。

Linux提供了相应的解决方案,来确保每个线程能同步的访问进程提供的公共资源,线程同步。简而言之,就是排排队大家一个一个来!

线程同步四种方法

  1. 互斥锁
  2. 信号量
  3. 条件变量
  4. 读写锁

互斥锁

又称互斥体或互斥量,是最简单的一种线程同步机制,顾名思义,当一个线程访问的时候,就会把资源“”上,直到访问结束才会解锁,给其他线程访问。

互斥锁本身就是一个全局变量:unlocklock

  1. ”unlock“表示当前资源可以访问,第一个访问资源的线程将互斥锁修改为”lock“,访问完以后再修改为”unlock“
  2. "lock"表示线程正在访问资源,其他线程需要等待互斥锁的值为"unlock"才能继续访问

解铃还须系铃人,该线程负责的加锁,解锁也需要该线程

信号量

又称信号灯,控制同时访问公共资源的线程数量,当线程数量小于等于1时,这种信号量可以叫二元信号量,同理多的时候,叫多元信号量,是指同一时刻最后只有这么多个线程可以访问该资源

信号量的取值范围必须>=0;值得一提的是信号量可以执行加一减一的操作,而且这种操作还是原子操作来实现的。原子操作,你可以理解为多个线程修改信号量,但是在修改值的过程中互不干扰。

具体操作流程:

  1. 信号量不能小于零
  2. 线程访问资源时,信号量减一,访问完成加一
  3. 信号量为0时候,其他访问线程需要等待,知道大于0

信号量分类:二元信号量计数信号量

  1. 二元信号量初始值为1,信号量的值只有0和1,一定程度上替代互斥锁进行线程同步。
  2. 计数信号量,初始值大于1,可以允许多个线程同一时间访问同一资源,起到限制访问个数的作用。

条件变量

功能类似现实中的门,只有打开关闭两种状态,对应条件中的成立与不成立两种判定,一旦关闭,所有线程都不得访问该资源,一旦打开,那就恢复执行。通常条件变量和互斥锁是搭配使用的

条件变量的本质也是全局变量,它的功能是阻塞线程,直到收到条件成立的信号,被阻塞的程序才能继续执行。

具体流程:

  1. 阻塞线程,知道收到信号
  2. 向等待队列中一个或者所有线程发送条件成立的信号,解除被阻塞的状态。

为了避免多线程抢资源的情况发生,条件变量必须和互斥锁搭配使用。

读写锁

如果很多线程只是进行读取操作,只有少部分是写操作(修改),可以使用读写锁。

读写锁的核心思想是将线程访问共同数据发出的请求分类:

  1. 读请求:只读,不修改共享数据
  2. 写请求: 存在修改共享数据的操作

当有多个读线程的时候,他们可以同时访问,但是写线程就必须要等他们读完才能访问,反过来也是,只不过写线程必须要一个一个来访问。读线程访问时候,读写锁称之为读锁写线程访问时候,读写锁称之为写锁

死锁

死锁:线程一直被阻塞的情况

比如:给线程加上互斥锁但是忘了解锁,那就会出现一直阻塞的情况。

避免死锁的建议

  1. 使用互斥锁,信号量,条件变量,读写锁的时候
    (1)占用互斥锁的进程要及时解锁
    (2)通过sem_wait()函数占用信号量资源的线程,及时调用sem_post()函数进行释放
    (3)当线程phtread_cond_wait()函数被阻塞时,一定要保证有其他线程唤醒此线程
    (4)无论线程占用的是读锁还是写锁,都要及时解锁

  2. POSIX标准中,很多阻塞线程的函数都提供两个版本tryxxx(),一种是timexxx();其中try是不会阻塞线程,time不会一直阻塞线程,多使用这两种可以大大降低死锁的概率。(pthread_mutex_lock,pthread_mutex_trylock)
    (sem_wait,sem_trywait)(pthread_cond_wait,pthread_cond_timewait)

  3. 多线程程序中,多个线程申请资源的顺序最好一致,比如线程1先申请matex1在申请matex2,而线程2先申请matex2,再申请matex1,就会发生顺序不一致导致的死锁。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值