Monad、Actor与并发编程--基于线程与基于事件的并发编程之争

将线程、事件、状态等包装成流的源。javascript

核心:解决线程的消耗和锁的效率问题。html

 

Java和Node.js能够说分别是基于线程和基于事件的两个并发编程表明,它们互相指责瞧不起对方,让咱们看看各类阵营的声音:java

 

基于事件的粉丝认为线程是一个坏主意,缘由有是:程序员

1. 你得显式的协调共享数据的锁,若是你忘记加锁,你就会获得中断坏的数据。编程

2. 依赖锁致使死锁。服务器

3. 它们难以调试多线程

4. 回调并无锁并发

5. 多线程在多核上的性能并不会比每一个单核一个线程性能更好。app

 

你应当尽量地避免线程,对于GUI和分布式系统或低端服务器不要用线程,只有处理CPU并发时才须要线程,若是必须使用线程,将线程隔离在核心内部,让大部分代码保持单线程。异步

 

而基于线程的粉丝认为Why events are a bad idea,反驳理由是:

1. 不少使用线程实现高并发却没有得到好性能?这其实假象,有人建立一个可扩展到100,000的线程库,其性能匹配SEDA的基于事件实现的性能。

2.线程限制流程控制?线程派分析了基于事件的系统, 发现这些应用控制流程模式有三种:call-return, parallel calls和 pipeline. 这些都很容易使用线程表达。

3.线程同步锁过重量?协调式多任务(协程)能让线程轻量等同于基于事件的并发。

4.线程堆栈没有足够效率管理活动状态?不是,一个新的动态增加性堆栈stack模型能够解决这个问题。

5.线程会阻止运行时刻进行优化调度决定?不是这样,Lauer 和Needham 都显示不是这种状况。

线程派认为现代服务器虽然须要并发处理大量的请求,可是代码处理每一个请求一般是有顺序的,咱们相信线程提供这两种状况下很好的编程抽象。

尽管事件系统在高并发下有很好的性能,可是咱们已经证实使用线程也会有相似性能(banq注:不过真的须要高手),因为语言提供编译时的分析使得线程简单,同样和基于事件系统能实现高并发。

 

线程派的改良表明能够首推Go的Goroutine和Python的coroutine协程,它们解决了直接基于OS线程致使线程上下文切换时带来的性能损耗,并且经过调度器保证非堵塞。Goroutine最大的特色可以让程序员以同步顺序代码的风格编写异步运行,Goroutine=coroutine协程 + user space threads + fibers + greenlets。由于绿色线程被封装在语言的API中,所以相比Node.JS显式处理异步IO,GO语言提供了隐式的异步处理IO,从而使得并发异步变得简单。

 

在GO语言的竞争之下,Node.JS一直探索如何避免回调陷阱,从Promise 到coroutine/Generators,直至演化到Javascript 7的async函数。从而也能够实现使用熟悉的顺序编程风格编写出异步代码,下面是使用JS 7的新的异步函数:

 

 

function* getStockPrice(name) {
    var symbol = yield getStockSymbol(name);
    var price = yield getStockPrice(symbol);
    return price;
}
var result = 
    spawn(getStockPrice.bind(null, "Pfizer"));
result.then(console.log, console.error);

<p>

 

Javascript 7主要亮点是在事件机制和异步编程的提高上,这两点主要体如今:

1. Object.observe使得模型和视图之间很容易同步。

2. async函数更易于异步编程,可以实现拉Pull或推Push。

 

http://www.jdon.com/idea/js/javascript7.html

 

以Node.js为主的事件派和Go的协程派打得热乎时,这时有了一种观点,既然大家二者都回避各自缺陷表现得不错,下面是就剩下使用者的爱好和技能选择了,能不能提供一种语言将这二者结合在一块儿?

 

Haskell倡导者提出经过语言统一多线程编程和事件编程,提供一种Monad函数,其内部封装了事件和多线程抽象,不管你是哪派粉丝,均可以使用这个Monad编程。以下图:A language-based approach to unifying events and threads

 


 

这种观点获得大多数人的赞成,这时被冷落一边的Scala的Actor模型站出来认为本身的Actor函数属于这种二者合一的Monad函数,见这里

 

固然,Go的绿色线程Goroutine与Actor仍是有区别的:Actor模型和CSP模型的区别

 

纵观并发编程发展,你们都是从IO这个串行化端口入手,神仙过海,各显神招,从当初Java的NIO 到Node.JS的异步IO 再到Go的Goroutine以及Netty 以及Actor模型等等,应该说,谁在Socket IO这个战场上性能和易用性表现得更好,谁就可能在并发编程整个领域得到全胜。

 

https://www.jdon.com/46921

相关文章
相关标签/搜索