多核处理器越来越普及,那有没有一种简单的办法,能够让我们写的软件释放多核的威力?答案是:Yes。随着Golang, Erlang, Scale等为并发设计的程序语言的兴起,新的并发模式逐渐清晰。正如过程式编程和面向对象一样,一个好的编程模式需要有一个极其简洁的内核,还有在此之 上丰富的外延,可以解决现实世界中各种各样的问题。本文以GO语言为例,解释其中内核、外延。
并发模式之内核
这种并发模式的内核只需要协程和通道就够了。其中协程负责执行代码,通道负责在协程之间传递事件。
并发编程一直以来都是个非常困难的工作。要想编写一个良好的并发程序,我们不得不了解线程, 锁,semaphore,barrier甚至CPU更新高速缓存的方式,而且他们个个都有怪脾气,处处是陷阱。笔者除非万不得以,决不会自己操作这些底层 并发元素。一个简洁的并发模式不需要这些复杂的底层元素,只需协程和通道就够了。
协程是轻量级的线程。在过程式编程中,当调用一个过程的时候,需要等待其执行完才返回。而调用一个协程的时候,不需要等待其执行完,会立即返回。协程十分 轻量,Go语言可以在一个进程中执行有数以十万计的协程,依旧保持高性能。而对于普通的平台,一个进程有数千个线程,其CPU会忙于上下文切换,性能急剧 下降。随意创建线程可不是一个好主意,但是我们可以大量使用的协程。
通道是协程之间的数据传输通道。通道可以在众多的协程之间传递数据,具体可以值也可以是个引用。通道有两种使用方式。
· 协程可以试图向通道放入数据,如果通道满了,会挂起协程,直到通道可以为他放入数据为止。
· 协程可以试图向通道索取数据,如果通道没有数据,会挂起协程,直到通道返回数据为止。
如此,通道就可以在传递数据的同时,控制协程的运行。有点像事件驱动,也有点像阻塞队列。这两个概念非常的简单,各个语言平台都会有相应的实现。在Java和C上也各有库可以实现两者。
只要有协程和通道,就可以优雅的解决并发的问题。不必使用其他和并发有关的概念。那如何用这两把利刃解决各式各样的实际问题呢?