自己如何实现自旋锁,互斥锁和读写锁
锁
C语言协程库实现
锁是很常见的同步原语,那么锁的实现原理是怎样的呢?下面我们就自己模拟实现一下各种锁来更好地理解锁的实现和代价.
自旋锁
自旋锁是一种成本较低的锁,因为它只会在当前cpu循环忙等直到获取到锁而不会让出控制权.
自旋锁的特点也使其只能用于保护操作较短的临界区,且不能睡眠.
代码实现
主要是通过cas等原子操作来模拟.
typedef volatile spin_lock_t;spin_lock(spin_lock_t *lock)
{do {if (cas(&lock, 0, 1) == 0) // cas循环判断,直到加锁成功.break;} while (1);
}spin_unlock(spin_lock_t *lock)
{atomic_set(&lock, 0); // 锁变量置0
}
互斥锁
用原子操作和信号量实现互斥锁
typedef struct {int val;int waiters;spin_lock_t lock;sem_t *sem;
}mutex_lock_t;mutex_lock(mutex_lock_t *lock)
{while(cas(&lock->val, 0, 1) != 0){sem_wait(sem);}}mutex_unlock(mutex_lock_t *lock)
{atomic_set(&lock->val, 0);sem_post(sem);
}
读写锁
用自旋锁和信号量实现读写锁
typedef struct {int readers;int writers;int writer_waiters;int cur_writer;sem_t *sem;spin_lock_t lock;
}mutex_rw_lock_t;mutex_rlock(mutex_rw_lock_t *lock)
{do {spin_lock(lock->lock);if (lock->writers == 0){break;}else{spin_unlock(lock->lock):sem_wait(sem);}}lock->readers++;spin_unlock(lock->lock);
}mutex_wlock(mutex_rw_lock_t *lock)
{do {spin_lock(lock->lock);if (!lock->readers && !lock->writers)break;spin_unlock(&lock->lock);sem_wait(&lock->sem);}lock->cur_writers = current();lock->writers++;spin_unlock(&lock->lock);
}mutex_unlock(mutex_rw_lock_t *lock)
{if(lock->cur_writers == current())mutex_wunlock(lock);elsemutex_runlock(lock);
}mutex_runlock(mutex_rw_lock_t *lock)
{spin_lock(&lock->lock);lock->readers--;spin_unlock(&lock->lock);sem_post(&lock->sem);
}mutex_wunlock(mutex_rw_lock_t *lock)
{spin_lock(&lock->lock);lock->writers--;lock->cur_writer = 0;spin_unlock(&lock->lock);sem_post(&lock->sem);
}
上面的读写锁实现有一个问题就是但读者很多时,可能会将写者饿死.一种改进的方法是将等待者进行排队.
自己如何实现自旋锁,互斥锁和读写锁相关推荐
- 自旋锁/互斥锁/读写锁/递归锁的区别与联系
自旋锁 互斥锁 读写锁 递归锁 互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁 ...
- Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...
一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...
- c/c++:线程同步(互斥锁、死锁、读写锁、条件变量、生产者和消费者模型、信号量)
目录 1. 概念 2. 互斥锁 3. 死锁 4. 读写锁 5. 条件变量 5.1 生产者和消费者模型 6. 信号量 1. 概念 线程同步: > 当有一个线程在对内存进行操作时,其他线程都不可以对 ...
- android 线程互斥锁,线程锁(互斥锁Mutex)及递归锁
一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...
- 【Java锁体系】ReadWriteLock读写锁是什么?什么是读写锁
[Java锁体系]ReadWriteLock读写锁场景 一.背景 像我们所知的ReentrantLock.synchronized关键字都是排它锁,这些锁在同一时刻只允许一个线程访问. 而读写锁允许在 ...
- 互斥量、读写锁长占时分析的利器——valgrind的DRD
在进行多线程编程时,我们可能会存在同时操作(读.写)同一份内存的可能性.为了保证数据的正确性,我们往往会使用互斥量.读写锁等同步方法.(转载请指明出于breaksoftware的csdn博客) 互斥量 ...
- unix c线程同步的三种方法:互斥量、读写锁以及条件变-xhb8413-ChinaUnix博客
unix c线程同步的三种方法:互斥量.读写锁以及条件变-xhb8413-ChinaUnix博客 unix c线程同步的三种方法:互斥量.读写锁以及条件变 2012-03-30 14:42:38 分类 ...
- iOS开发中自旋和互斥锁的理解以及所有锁的性能比较
补充: 可以看到除了 OSSpinLock 外,dispatch_semaphore 和 pthread_mutex 性能是最高的.苹果在新系统中已经优化了 pthread_mutex 的性能,所以它 ...
- 可重入锁(递归锁) 互斥锁属性设置
前言: 上一次刷博客的时候,看到了自旋锁,通过学习Linux内核,对自旋锁有了一定的了解.在学习的过程中看到这么一句话--自旋锁是不可递归的.自旋锁不可递归,难道有可以递归的锁?带着这个问题,我们来看 ...
最新文章
- pycharm第一个Python程序
- oracle数据转成sqlserver,oracle数据库转换到Sqlserver的几点经验
- 为什么CRM WebClient UI每次点了回车都会触发到后台的roundtrip
- LabVIEW串口接收实例
- python 模块路径查找 及 添加
- 网络编程之信号(处理僵尸进程的终极办法)之初识信号捕捉器
- VB.NET中DataGridView控件
- MAC 升级 node.js 的快捷方法
- 树莓派PICO:DS1302时钟芯片(MicroPython)
- 施乐服务器装系统闪EE,施乐7535755633755575驱动安装教程
- STM32F030使用RTC周期性唤醒STOP模式
- Linux Kernel Makefiles(转)
- 网络显示连接正常,就是网页打不开(也适用于ie可以打开,google打不开情况)
- 运行vue项目时,如果一直报eslint语法错误的解决方案
- MySQL求百分比带百分号%
- Unirech阿里云国际版云服务器ecs的应用场景有哪些?
- [编程题] 大富翁游戏(美团点评2017秋招)
- D - Silver Cow Party J - Invitation Cards 最短路
- 使用树莓派制作的远程开门器
- 解决(无法启动服务,错误1068:依赖服务或组无法启动、telnet)