关于并发和并行

阅读更多

并发和并行随着云计算的兴起,现在是一个热门的研究领域, 回顾一下问题的产生,当服务器需要处理大量连接时:

1、最简单的办法是,一个连接来了之后, fork一个线程去处理,当然,也可以用进程, 如php, 但大部分都是以线程的方式去处理, 这种方式的缺点是:现代操作系统中的线程开销尽管比进程小很多, 但所占的资源仍然很大, 需要保存上下文的运行环境, 当前的指针需要保存在堆栈中, 而且来回切换时,线程的资源都处在不释放状态, 所以一台机器最多跑5k左右的线程, 实际上线程数目超过1k, 可靠性和性能会大大降低,并且存在c10k的问题

2、采用事件驱动的办法, 当一个事件来了之后, 将处理逻辑委派给一个或者多个线程去处理,当前线程立刻进入下一个请求的处理,当handler进程的工作完成之后, 会执行一段callback逻辑做善后工作, 这段callback逻辑是事先准备好的, 这种方式是目前最流行的处理方式, 利用几个线程线程(包括请求处理进程、队列线程、handler线程等)完成高并发的需求,但这种方式的缺点是处理时延比较高, 无法充分利用CPU资源, 而占用了很大的内存资源:拿空间换时间

3、Actor模型

当一个请求来了之后, 则委派给一个Actor处理, 和事件驱动的区别是, 这些Actor之间不共享任何资源, 可进行并行处理, 事件驱动模型和Actor模型很容易被搞混淆, 如果事件驱动模型来一个请求则委派一个线程去处理并且这些线程之间不共享资源,不会出现锁的问题, 则可以认为这种事件驱动模型等价于Actor模型, Scala的Actor模型就是这么处理的, Actor会被代理到线程处理, 海量的Actor会被代理到一个JVM线程池处理,这样提升了很大的效率,而这种映射是scala帮你做好了; 而Erlang中Actor模型则更加彻底, 其实是OTP实现了操作系统中的线程的功能, 这些“线程”叫做process, 只不过这些process占用的资源很少, 也不共享任何资源, 这样每个actor可以跟process一一对应

 

总结一下:

第一种模型可以应对的并发数,最多几千的级别

第二种模型的并发数在几万的级别,不过根据机器性能,也可以往上提升到10w

第三种模型对应的并发数在几百万的级别,如Erlang和akka

你可能感兴趣的:(关于并发和并行)