Linux线程同步之互斥锁和读写锁

1.线程的同步:(同指的是协同)
保证对共享资源(公共区域数据)的访问是按照一定的顺序进行的,如果没有设置对应的同步机制,在访问资源的时候,就会出现数据混乱的现象。

2.注意互斥锁是一把建议锁,而锁本身不具备强制性。假设一共有3个线程,其中2个线程进行了加锁的操作,而其中一个线程没有进行加锁,那么该线程是可以直接访问该共享资源的。为了避免这种现象的产生,3个线程在访问共享资源之前,都应该进行加锁的操作,对数据进行处理之后,再进行解锁的操作哦。加锁解锁的操作是由代码的执行逻辑去控制的,因此决定权在我们手中。

3.关于互斥锁的应用:分为以下几个步骤:

  1. pthread_mutex_t lock//创建互斥锁 ,这里的pthread_mutex_t本质是一个结构体,为了简化理解,可以将其看作整数对待。初始化的时候pthread_mutex_t 的取值为1.
  2. pthread_mutex_init(&lock,NULL) //初始化
  3. pthread_mutex_lock(&lock) //加锁
  4. 访问共享数据
  5. pthread_mutex_unlock(&lock) //解锁
  6. pthread_mutex_destory(&lock) //销毁锁
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

这里的restrict关键字是用于限制指针,告诉编译器,所有修改该指针指向内存中内容的操作,只能通过本指针完成。

不能通过除本指针以外的其他变量或指针修改
锁应用的一个简单例子:不加锁的情况下,由于多线程是并发执行的,因此打印的时候,hello之后不一定是world,加锁之后可以实现。
在这里插入图片描述
加锁之后的情况:
在这里插入图片描述
lock和trylock:
lock 加锁失败后线程会阻塞,等待资源释放,而trylock加锁失败后不会阻塞,而是返回错误码。

死锁:(课程里面说的很粗糙,打算还是要看王道操作系统里面的)

  1. 加锁两次会造成死锁:线程直接就阻塞了
  2. 线程1拥有A锁,请求获取B锁。线程2拥有B锁,请求获取A锁。

读写锁:适用于大量的读数据,少量的修改数据的情况。
遵循:读时共享,写时独占的原则。
读写锁只有1把,被设置为全局的读写锁,加锁的时候只是考虑是以读锁的方式加锁还是以写锁的方式进行加锁。
因此对应的加锁函数是有两个,而解锁函数只有1个(毕竟只有1把锁)
为什么不适用互斥锁:
多线程对于全局变量进行读操作,一旦互斥锁对某个全局变量加锁成功,那么其他的线程就会阻塞掉。
而使用读写锁,假设有1000个线程,互斥锁对某个全局变量加读锁之后,所有的线程都可以访问该资源。
需要注意的是,写锁的优先级高于读锁。当以写模式对数据进行加锁,其他线程的读锁是没办法访问数据的。

性质:

  1. 读写锁是“写模式加锁”时, 解锁前,所有对该锁加锁的线程都会被阻塞。
  2. 读写锁是“读模式加锁”时, 如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞。
  3. 读写锁是“读模式加锁”时, 既有试图以写模式加锁的线程,也有试图以读模式加锁的线程。那么读写锁会阻塞随后的读模式锁请求。优先满足写模式锁。读锁、写锁并行阻塞,写锁优先级高。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值