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);
}

上面的读写锁实现有一个问题就是但读者很多时,可能会将写者饿死.一种改进的方法是将等待者进行排队.

自己如何实现自旋锁,互斥锁和读写锁相关推荐

  1. 自旋锁/互斥锁/读写锁/递归锁的区别与联系

    自旋锁 互斥锁 读写锁 递归锁 互斥锁(mutexlock): 最常使用于线程同步的锁:标记用来保证在任一时刻,只能有一个线程访问该对象,同一线程多次加锁操作会造成死锁:临界区和互斥量都可用来实现此锁 ...

  2. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  3. c/c++:线程同步(互斥锁、死锁、读写锁、条件变量、生产者和消费者模型、信号量)

    目录 1. 概念 2. 互斥锁 3. 死锁 4. 读写锁 5. 条件变量 5.1 生产者和消费者模型 6. 信号量 1. 概念 线程同步: > 当有一个线程在对内存进行操作时,其他线程都不可以对 ...

  4. android 线程互斥锁,线程锁(互斥锁Mutex)及递归锁

    一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...

  5. 【Java锁体系】ReadWriteLock读写锁是什么?什么是读写锁

    [Java锁体系]ReadWriteLock读写锁场景 一.背景 像我们所知的ReentrantLock.synchronized关键字都是排它锁,这些锁在同一时刻只允许一个线程访问. 而读写锁允许在 ...

  6. 互斥量、读写锁长占时分析的利器——valgrind的DRD

    在进行多线程编程时,我们可能会存在同时操作(读.写)同一份内存的可能性.为了保证数据的正确性,我们往往会使用互斥量.读写锁等同步方法.(转载请指明出于breaksoftware的csdn博客) 互斥量 ...

  7. unix c线程同步的三种方法:互斥量、读写锁以及条件变-xhb8413-ChinaUnix博客

    unix c线程同步的三种方法:互斥量.读写锁以及条件变-xhb8413-ChinaUnix博客 unix c线程同步的三种方法:互斥量.读写锁以及条件变 2012-03-30 14:42:38 分类 ...

  8. iOS开发中自旋和互斥锁的理解以及所有锁的性能比较

    补充: 可以看到除了 OSSpinLock 外,dispatch_semaphore 和 pthread_mutex 性能是最高的.苹果在新系统中已经优化了 pthread_mutex 的性能,所以它 ...

  9. 可重入锁(递归锁) 互斥锁属性设置

    前言: 上一次刷博客的时候,看到了自旋锁,通过学习Linux内核,对自旋锁有了一定的了解.在学习的过程中看到这么一句话--自旋锁是不可递归的.自旋锁不可递归,难道有可以递归的锁?带着这个问题,我们来看 ...

最新文章

  1. pycharm第一个Python程序
  2. oracle数据转成sqlserver,oracle数据库转换到Sqlserver的几点经验
  3. 为什么CRM WebClient UI每次点了回车都会触发到后台的roundtrip
  4. LabVIEW串口接收实例
  5. python 模块路径查找 及 添加
  6. 网络编程之信号(处理僵尸进程的终极办法)之初识信号捕捉器
  7. VB.NET中DataGridView控件
  8. MAC 升级 node.js 的快捷方法
  9. 树莓派PICO:DS1302时钟芯片(MicroPython)
  10. 施乐服务器装系统闪EE,施乐7535755633755575驱动安装教程
  11. STM32F030使用RTC周期性唤醒STOP模式
  12. Linux Kernel Makefiles(转)
  13. 网络显示连接正常,就是网页打不开(也适用于ie可以打开,google打不开情况)
  14. 运行vue项目时,如果一直报eslint语法错误的解决方案
  15. MySQL求百分比带百分号%
  16. Unirech阿里云国际版云服务器ecs的应用场景有哪些?
  17. [编程题] 大富翁游戏(美团点评2017秋招)
  18. D - Silver Cow Party J - Invitation Cards 最短路
  19. 使用树莓派制作的远程开门器
  20. 解决(无法启动服务,错误1068:依赖服务或组无法启动、telnet)

热门文章

  1. 超融合的“一出好戏”,岂有不红之理?
  2. 2021年全国A级景区矢量分布数据(11969条)
  3. AUTO CAD Electrical缺少AceRedist文件
  4. ./mvnw无法运行的问题处理
  5. Vue项目中用vue-video-player实现直播效果(m3u8格式)
  6. Python导入模块报错问题的分析
  7. CAS算法的理解及应用
  8. PAT B1024/A1073
  9. Android 接口回调例子
  10. SRv6的重要参考文献