Skip to content

docs: 更新文档描述及typo错误 #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,21 @@

协程切换比线程切换快主要有两点:

(1)协程切换**完全在用户空间进行**线程切换涉及**特权模式切换,需要在内核空间完成**;
(1)协程切换**完全在用户空间进行**线程切换涉及**特权模式切换,需要在内核空间完成**;

(2)协程切换相比线程切换**做的事情更少**,线程需要有内核和用户态的切换,系统调用过程。



#### 协程切换成本:

协程切换非常简单,就是把**当前协程的 CPU 寄存器状态保存起来,然后将需要切换进来的协程的 CPU 寄存器状态加载的 CPU 寄存器上**就 ok 了。而且**完全在用户态进行**,一般来说一次协程上下文切换最多就是**几十ns** 这个量级。
协程切换非常简单,就是把**当前协程的 CPU 寄存器状态保存起来,然后将需要切换进来的协程的 CPU 寄存器状态加载到 CPU 寄存器上**就 ok 了。而且**完全在用户态进行**,一般来说一次协程上下文切换最多就是**几十ns** 这个量级。



#### 线程切换成本:

系统内核调度的对象是线程,因为线程是调度的基本单元(进程是资源拥有的基本单元,进程的切换需要做的事情更多,这里占时不讨论进程切换),而**线程的调度只有拥有最高权限的内核空间才可以完成**,所以线程的切换涉及到**用户空间和内核空间的切换**,也就是特权模式切换,然后需要操作系统调度模块完成**线程调度(task***struct),*而且除了和协程相同基本的 CPU 上下文,还有线程私有的栈和寄存器等,说白了就是上下文比协程多一些,其实简单比较下 task_strcut 和 任何一个协程库的 coroutine 的 struct 结构体大小就能明显区分出来。而且特权模式切换的开销确实不小,随便搜一组测试数据 [3],随便算算都比协程切换开销大很多。
系统内核调度的对象是线程,因为线程是调度的基本单元(进程是资源拥有的基本单元,进程的切换需要做的事情更多,这里占时不讨论进程切换),而**线程的调度只有拥有最高权限的内核空间才可以完成**,所以线程的切换涉及到**用户空间和内核空间的切换**,也就是特权模式切换,然后需要操作系统调度模块完成**线程调度(task_struct)**,而且除了和协程相同基本的 CPU 上下文,还有线程私有的栈和寄存器等,说白了就是上下文比协程多一些,其实简单比较下 task_strcut 和 任何一个协程库的 coroutine 的 struct 结构体大小就能明显区分出来。而且特权模式切换的开销确实不小,随便搜一组测试数据 [3],随便算算都比协程切换开销大很多。



Expand Down Expand Up @@ -222,7 +222,7 @@ KiB Swap: 969960 total, 563688 free, 406272 used. 168812 avail Mem

free的mem为1675844,

所以**20万个协程占用了约 50万KB****平均一个协程占用约2.5KB**
所以 **20万个** 协程占用了约 **50万KB**, **平均** 一个协程占用约 **2.5KB**



Expand Down
9 changes: 4 additions & 5 deletions 5、channel.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@

* 给一个已经关闭的 channel 发送数据,引起 panic

* 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个零值
* 从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回 **一个零值 和 false** (ex: `val,ok:= <-ch1`)

* 无缓冲的channel是同步的,而有缓冲的channel是非同步的

以上5个特性是死东西,也可以通过口诀来记忆:“空读写阻塞,写关闭异常,读关闭空零”。


以上5个特性是死东西,也可以通过口诀来记忆:“读写**空**阻塞,写**关闭**异常,读**关闭空**零假”。

![](images/169-channel异常情况总结.png)


> 执行下面的代码发生什么?
Expand Down Expand Up @@ -59,7 +58,7 @@ func main() {



15字口诀:“空读写阻塞,写关闭异常,读关闭空零”,往已经关闭的channel写入数据会panic的。因为main在开辟完两个goroutine之后,立刻关闭了ch, 结果:
15字口诀:“读写**空**阻塞,写**关闭**异常,读**关闭空**零假”,往已经关闭的channel写入数据会panic的。因为main在开辟完两个goroutine之后,立刻关闭了ch, 结果:

```
panic: send on closed channel
Expand Down
Binary file added images/169-channel异常情况总结.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.