云服务器

写得好不如选得好--Go并发之美

2017-06-22 10:32:33 0

多核服务器越来越普及,如何让服务器发挥出最大性能是所有编码人员最关心的事之一。先简单说说传统两种并发模式:

Future模式

当客户端发送一个长时间的请求,服务器不需要等待数据处理完成就返回一个伪造的数据,客户端可以执行其他操作,再去服务器拿取处理后的数据。这个模型可以充分利用等待的时间。

Master-Worker模式

Master-Worker是并发模型中最常用的模型之一,Master负责接收和分发任务,Worker负责处理任务 。

但是!!!如果想应用到生产环境中并且能处理比较高的并发,这两种模式的代码实现实在是太复杂,太复杂,太复杂!!!重要的事情说3遍,我是打算写一个C版的Master-Worker模式的,下面是我从入门到放弃的伪代码:

线程安全? 消息通知?

不用9999行代码,只需99,Go帮你用最少的代码写出高效的性能!

func handle(w string,sec int32){ //工作逻辑 } func main(){ go handle("test1",2) go handle("test2",3) time.Sleep(10) }这里问题又来了,能不能告诉主线程,这些任务都结束呢?答案:yes 这里需要引入chanel概念,上面的代码可以优化为:+1::

var mygoroutine chan int func handle(w string,sec int32){ //工作逻辑 c <- 1 } func main(){ mygoroutine = make(chan int) go handle("test1",2) go handle("test2",3) <- mygoroutine <- mygoroutine }* channel使用make 来创建 int是说明这个管道是什么数据类型

  • 向channel发送消息 c <- 1 ,简单,形象,有点像重定向
  • 从channel输出数据 <- c
  • 为什么会输出两次? 因为启用了2个goroutine
  • 什么叫goroutine? 其实goroutine可以把他当成一个线程,但是它是一个代替原来线程概念的最小调度单位,他就是golang中的线程,一旦运行goroutine时,先去当当前线程查找,如果线程阻塞了,则被分配到空闲的线程,如果没有空闲的线程,那么就会新建一个线程。注意的是,当goroutine执行完毕后,线程不会回收退出,而是成为了空闲的线程。
channel分为两种:一种是有buffer的,一种是没有buffer的,默认是没有buffer的

打个比喻

无缓冲的 就是一个送信人去你家门口送信 ,你不在家 他不走,你一定要接下信,他才会走。

无缓冲保证信能到你手上

有缓冲的 就是一个送信人去你家仍到你家的信箱 转身就走 ,除非你的信箱满了 他必须等信箱空下来。

有缓冲的 保证 信能进你家的邮箱

就是这个缓冲channel和goroutine在其他语言工具中是要多少行代码来实现,在go的世界里,这些东西都是so easy!!

 

上一篇: 无

微信关注

获取更多技术咨询