在Go中是通过chan来进行通信的,即go的哲学:通过通信来实现共享内存
多线程为什么不安全
程序除了通过共享一段内存之外,每一个 CPU 核心都有它本地的缓存,而 CPU 上的缓存是不共享的, 而线程可以同时在不同的 CPU 上执行
CPU 的执行过程是,先从内存中读取数据到 CPU 中,CPU 做完计算再更新到内存中。 这样一来,就有可能存在不同线程对同一段内存同时读写的问题
多线程不安全是因为多个线程可以对同一段内存进行读写,这就存在其中一个线程还没来得及更新内存, 然后另一个线程读取到的数据是旧的
Go channel
总结
-
go 里面通过
chan来实现协程之间的通信,chan大概就是一个协程给另一个协程发送信息的代理。 -
多线程程序执行的时候,因为有 CPU 缓存,然后需要对同一块内存进行并发读写,可能会导致数据竞争的问题。
-
在很多语言中,都提供了锁的机制,来保护一片内存同一时刻只能一个线程操作,比如 java 里面的
synchronized关键字。 -
go 里面很多情况下,在不同协程之间通信都是使用
chan来实现的。 -
进程会有阻塞态、运行态,go 里面的协程也有阻塞的状态,当需要的资源得不到满足的时候就会陷入阻塞。比如等待别的协程往
chan里面写入数据。 -
chan的几种常见操作:make创建、<-chan读、chan<-写、len获取chan中未读取的元素个数、cap获取chan的缓冲区容量。 -
chan类型上不加<-表示是一个可读可写的chan,<-chan T表示只读chan,chan<- T表示只写chan,双向的chan可以转换为只读或者只写chan,但是反过来不行,只读chan和只写chan之间也不能相互转换。 -
协程的阻塞跟不阻塞,很简单的判断方式就是,发送的时候就看有没有地方能接得住,接收的时候就看有没有数据可以拿,没有则陷入阻塞。
-
<-是 go 语言在设计层面提供给开发者的一种语法糖,chan底层是一个很复杂的结构体。 -
for...range结构在遍历chan的时候不用判断返回值是否有效,因为返回值无效的时候会退出循环。 -
我们可以通过
select来同时等待多个chan的操作返回