线程同步,锁的相关问题

线程同步过程中,为使程序中多个线程共享资源,需要使用互斥量(锁)来进行同步,同一时间只允许一个线程访问共享资源。如果有多个锁(一个锁可视为一个共享资源)的话,在使用锁的过程中,最重要的就是如何避免死锁。
避免死锁的方法
1、控制互斥量加锁的顺序来避免死锁,使每个线程加锁的顺序总是一致,释放锁的顺序与加锁的顺序相反;
2、若锁过多,无法排序。若线程获取不了当前要申请的锁,则释放自己已经占有的锁,过一段时间再试。此时申请锁要使用pthread_mutex_trylock()方法,此方法在申请锁的时候如果获取不了,则立马返回EBUSY,根据此可以释放自己占有的锁;
3、在线程执行阶段,可以在线程内设置一个timer,若超过预期的时间还没有释放锁,那么就强制性的释放锁。在申请锁的时候,可以设置带有超时限制的锁(pthread_mutex_timedlock()方法),若在指定的时间内如果获取不了锁,则放弃获取,返回错误码ETIMEOUT,这就避免一直申请导致死锁(使用带超时限制的锁,如果不结合第二个方法,那么也会造成死锁,因为超时限制的锁并不会释放本身已经占有的锁,所以其他线程仍然可能会死锁)。
锁的种类:
1、pthread_mutex_t:互斥锁,一次只能有一个线程获得;
2、pthread_rwlock_t: 读写锁(共享互斥锁),在读模式下,可以多个线程获得锁,进行只读(pthread_rwlock_rdlock()方法获得);在写模式一下,只允许一个线程获得锁,对共享资源进行写(pthread_rwlock_wrlock()获得),适用于读的次数远大于写的次数。注意,当有一个线程申请写锁时,读写锁通常会阻塞随后的读模式锁请求,可以避免读模式锁长期占用,而等待的写模式锁一直得不到满足;
3、pthread_cond_t:条件变量,其实不算是锁的一种,他和锁配合使用,为多线程提供一个会合的场所。注意,条件本身是有互斥量保护的,线程在改变条件状态之前必须首先锁住互斥量。只有锁住互斥量之后,线程才能感知条件状态的改变。通过函数pthread_cond_wait(pthread_cond_t cond,pthread_mutex_t mutex)来实现,线程执行此函数以后,便释放获得的锁mutex,此线程在pthread_cond_wait处阻塞,等到其他线程调用唤醒线程pthread_cond_signal(pthread_cond_t cond),此函数唤醒至少一个等待cond变量条件的线程(注意:不是使用cond变量名的线程不会被唤醒)。该线程被唤醒以后,则继续此线程执行,可以判断此线程所需要的资源是否被其他线程填写,若判断为空,继续阻塞,这就达到了多线程会合的目的。

pthread_mutex_lock(&mutex);
while(workq == NULL)//每次被唤醒都要检查workq是否被填满,填满以后才进行线程其他操作,否则一直等待。
{
    pthread_cond_wait(&cond,mutex);
}

4、pthread_spinlock_t:自旋锁,与互斥量类似,不过,他不是通过休眠时进程阻塞,而是在获取锁之前一直处于忙等阻塞状态(自旋),当线程使用自旋锁时,在自旋等待到锁变为可用过程中,一直占用CPU资源,CPU不能做其他事情。适用于:锁被持有的时间短,且线程不希望在重新调度上花成本。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值