锁与原子操作
先说 golang 的 包(package)
- golang 提供的服务跟PHP是不同的,golang 的每个服务是一个不停止的进程,一直在内存中运行接收外部的请求进行处理,
而 PHP 是外部请求过来 nginx 或 apache 开启一个线程,这个线程通过CGI 加载PHP文件运行PHP程序,等这个请求处理完成,
这个线程也就关闭了。那么golang运行就有了下面这个问题。 - 因为 golang 有的包里有全局变量,其它程序引入这个包,就可以操作这个全局变量,很多个程序引入这个包,那就意味着很多
程序可以操作这个全局变量,问题来了: 对这个变量有读有写,那么会不会引起资源竞争呢?答案是肯定的。此时对 这个全局变量就需要
加锁,一旦加锁,最好所有的操作这个变量的地方都加锁
说一说原子操作
- 先说一说没有原子操作会产生的问题
- 先说下内核对各个进程的切换和调度
- 单核CPU也是可以同时处理多个程序(进程)的,这是什么原因呢?原因是 操作系统可以快速地在多个进程之间进行切换(也被称为
进程间的上下文切换), 以产生多个进程在同时运行的假象,每个进程都以为自己独占了CPU。这就是多任务操作系统这个称谓的由来。
- 单核CPU也是可以同时处理多个程序(进程)的,这是什么原因呢?原因是 操作系统可以快速地在多个进程之间进行切换(也被称为
- 再说下产生问题的场景
- 现在有 A,B 两个进程,有一个函数,这个函数的作用是往文件里写入10个字符串,写入前会判断文件里是否有10个字符串,如果没有则写入10个字符
- A进程开始调用这个函数,文件里没有10个字符 A进程开始写入
AAA
写入了3个字符 此时 CPU 切换进程 让B进程开始运行,B进程调用这个函数
此时文件里没有10个字符,B进程也开始写入AAA
轮流切换,那最后文件里会是10个字符吗?最后文件里肯定不止10个字符。
- 上面的场景产生了一个问题: 一个进程怎样能不被中断呢?引入了 原子操作 的概念
- 先说下内核对各个进程的切换和调度
锁与原子操作
- 从上面可以看出,原子操作跟锁有些相似 都是保证对某一步操作保持占有。但是它们有一个明显的不同。原子操作是不能被中断的。锁操作对是否可以被中断
却没有强制的规定,只要保证一个访问者在锁中的时候其他访问者不会被放进来就可以,这也意味着它们的强度是不同的。
应用场景
- 锁一般是操作一个变量的时候用 锁机制
- 而原子操作一般是读取文件的时候使用