相信大家都在官网看到这样一段话,“不要通过共享内存来通信,要通过通信开共享内存”。
要理解这段话,首先要复习进程间通信和线程间通信的方式:
Linux进程间通信:管道(匿名管道和有名管道)、信号、消息队列、共享内存、信号量、套接字(socket)
Linus线程间通信:互斥量、信号量、条件变量
Windows进程间通信:管道、共享内存、消息队列、信号量、套接字(socket)
Windows线程间通信:临界区、互斥量、事件
go语言比较特别,它的线程(协程)支持管道(pipe),为啥这么说呢?
因为管道在系统上,是进程间通信方式。如果这里不明白,把前面介绍Linux进程通信,Linux线程通信,Windows进程通信,Windows线程通信的再多看几遍。
共享内存在Windows和Linux中是用来做进程间通信的,很明显go不支持,因为go用的是线程。
但是go语言的线程支持管道(channel,在系统中是用来做进程间通信的),而管道的好处就是天然的支持阻塞,而共享内存(共享变量)需要反复加锁,解锁,等待。
再啰嗦一点,go语言实现了自己的调度器,在用户态多线程调度,当一个线程阻塞时,它会把资源分给没阻塞的线程。这点和多线程模型有很大的区别,以nodejs为例,它有一个主线程和一堆IO线程,但是它没有自己的调度器,而是依赖操作系统来进行调度。