<commit_before>---
title: 各种锁:自旋锁/互斥锁/读写锁/分布式锁
date: 2016-04-29 00:00:00
categories:
- code
tags: 
- lock
mathjax: true
description: 
---

# 锁
锁在计算机的世界里随处可见，当大家都想操作一个资源的时候，如果一窝蜂涌进来，就会出事的。
举个例子，加入说有2个线程都在操作一个共享资源（一个int），给他+1。我们知道+1不是原子操作，所谓原子操作，就是如果这个操作开始执行了，那么就不会被打断。看过汇编的同学都知道，+1需要先mov然后在add，如线程1mov了，然后执行线程2的mov，就会出问题。轻则数据错误，重则程序崩溃。感觉这个例子不太恰当，还是领会精神吧。为了保护我们的操作，那么就需要使得这个共享资源的操作变成原子的，这就需要锁了。
在并发编程中，尽量少用锁，能不用就不用，因为锁的开销很大很大。尽量让不同的执行单元操作各自独立的数据，如果不可避免要用到锁，那么锁的范围要尽量小。


<!--more-->
# 自旋锁vs互斥锁

类|特征|使用场景
---|---|---
自旋|不会休眠，不停重试，直到获得锁|锁住的代码执行时间很短。因为休眠再唤醒的开销很大。如果时间短，那么自旋的开销就很小
互斥|休眠，等锁被释放才会被唤醒|锁住的代码要执行很久，如果是自旋锁，就会不停尝试，被锁住的代码分不到足够的时间片，但是性能下降

# 读写锁
场景：读多写少
条件：
- 只要没有写锁，就能获取到读锁
- 只有没有任锁，才能获取到写锁

----------------------------

`本博客欢迎转发,但请保留原作者信息`
github:[codejuan](https://github.com/CodeJuan)
博客地址:http://blog.decbug.com/<commit_msg>example<commit_after>---
title: 各种锁:自旋锁/互斥锁/读写锁/分布式锁
date: 2016-04-29 00:00:00
categories:
- code
tags: 
- lock
mathjax: true
description: 
---

# 锁
锁在计算机的世界里随处可见，当大家都想操作一个资源的时候，如果一窝蜂涌进来，就会出事的。
举个例子，加入说有2个线程都在操作一个共享资源（一个int），给他+1。我们知道+1不是原子操作，所谓原子操作，就是如果这个操作开始执行了，那么就不会被打断。看过汇编的同学都知道，+1需要先mov然后在add，如线程1mov了，然后执行线程2的mov，就会出问题。轻则数据错误，重则程序崩溃。感觉这个例子不太恰当，还是领会精神吧。为了保护我们的操作，那么就需要使得这个共享资源的操作变成原子的，这就需要锁了。
在并发编程中，尽量少用锁，能不用就不用，因为锁的开销很大很大。尽量让不同的执行单元操作各自独立的数据，如果不可避免要用到锁，那么锁的范围要尽量小。


<!--more-->
# 自旋锁vs互斥锁

## 举个例子


- 互斥锁：假如说你想进入一个房间，但是这个房间里已经有人了。那么就进不去，这个时候你就先睡一觉，等里边的人出来把你叫醒，然后你再进去。
- 自旋锁：还是这个房间，房间里有人，你不会睡着，只会每过一分钟就看房间里的人出来了么，如果没出来，那么就继续不停查看。如果出来了，你就进去。

对应到系统，就是你这个线程想获取这个锁，但是这个锁被别的线程持有了，那么你这个线程就得休眠，等待锁释放后再被唤醒。要知道，休眠再唤醒的开销很大，所以就出了自旋锁。自旋锁不会休眠，会不停的尝试。

类|特征|使用场景
---|---|---
自旋|不会休眠，不停重试，直到获得锁|锁住的代码执行时间很短。因为休眠再唤醒的开销很大。如果时间短，那么自旋的开销就很小
互斥|休眠，等锁被释放才会被唤醒|锁住的代码要执行很久，如果是自旋锁，就会不停尝试，被锁住的代码分不到足够的时间片，但是性能下降


# 读写锁
场景：读多写少
条件：
- 只要没有写锁，就能获取到读锁
- 只有没有任锁，才能获取到写锁

----------------------------

`本博客欢迎转发,但请保留原作者信息`
github:[codejuan](https://github.com/CodeJuan)
博客地址:http://blog.decbug.com/
{'fraction_non_alphanumeric': 0.17391304347826086, 'fraction_numerical': 0.020953378732320588, 'mean_word_length': 6.925311203319502, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1641086', 'n_tokens_mistral': 1643, 'n_tokens_neox': 1919, 'n_words': 63}