携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
Go语言具有并发与协程、基于消息传递的通信方式、defer机制、高性能HTTP Server等特性。在服务端的开发中,Go语言能抓住开发人员的痛点,以最简单、直接、高效、稳定的方式来解决问题。在构思本文描述的搜索引擎时,主要考虑了Go并发与协程的特性以及基于消息传递的通信方式的特性选择了使用Go语言进行服务的开发,并利用Go语言的这两个特性对系统进行了设计。
goroutine
虽然有很多语言都支持多进程或多线程的并发编程方式,但是对于并发的控制往往都非常复杂。不同于传统的多进程/多线程,Go语言的并发执行单元是goroutine,本质上是协程。
协程,又称为用户级线程,对内核是透明的,操作系统并不感知协程的存在,而是由用户自主调度。goroutine不同于协程的地方在于Go语言在系统调用、runtime等多个方面对goroutine的调度进行了封装处理,可以在某个goroutine长时间未执行或系统调度时,自动将当前goroutine占用的CPU让出去给其他goroutine使用,即从语言层面支持了协程[6]。使用goroutine,只需要使用Go语言提供的go关键字即可,操作十分简单,对比Java等语言更直接、简洁,且在内存消耗、切换调度开销方面goroutine都比传统的多进程/多线程方式少的多。
channel
channel是goroutine之间的一种通信方式,类似于UNIX中进程之间通信方式的管道,同时channel也是Go语言中的一种数据类型,类似于队列。作为goroutine的通信方式,每个channel都是一个通信机制,具有一个特殊的类型,通过channel一个goroutine可以向其他的goroutine发送这种类型的数据。
在异步并发编程中,不仅需要方便、快速的启动协程,协程之间的通信方式也十分重要。不同于其他大多数语言采用的通过共享内存的通信方式,Go语言采用了基于消息传递的通信方式进行协程之间的通信,且把消息通道(channel)作为一种数据类型,用户使用关键字chan即可定义,直接、方便、且保证了并发操作时的线程安全。