之前的相关基础并不牢固,也一直没有真正的接触过高并发的实际业务场景。(真是惭愧)最近了解了一下并行、串行和并发等等的概念,算是在为了未来业务的挑战做一些知识储备,所以自己稍微总结了一下,以下是个人的一些想法,希望大家能够指点一下。
并行和串行是一个对立的概念,应该是说,对CPU而言,同时只有一个线程在实际活动,这样应该是串行执行的。比如说是没有使用多线程模式的程序来说,CPU按照顺序在单一线程中执行,处理完成一个任务后处理下一个任务。相对来说,并行会对CPU(多核)而言存在多个线程同时进行操作。比如Golang在1.5版本中将GOMAXPROCS默认设置为CPU核心数,这样就实现了goroutine的并行执行。并行执行带来的挑战是对于多个CPU核心对于共同的资源出现争抢情况(比如IO),串行执行虽然没有这种问题,但是实际上对于多线程情况下,通常需要对共同的资源进行加锁操作,防止在多线程环境下对于相同数据进行操作时出现的冲突(如list)。
并发则是针对与多任务而言,能够在时间范围内处理的任务量。通常并发中的任务在CPU时间内是可以切换的,比如大家都在讨论的GIL而言,即便是Python提供了多线程库,但是实际上仍是在单个CPU核心上进行的多个线程来回切换的执行。这样实际上是进行了所谓的并发。并发和并行的区别应该是,对于并发而言,是可以如同Python一样,在单个CPU核心之中可以进行多个线程的任务,需要2个以上的任务;并行则是除了两个以上的任务以外,还需要2个以上的CPU核心。
但是对Python而言,并发受到GIL的限制,对于当前使用的CPU核心以外的核心无法进行利用,因此通常在进行高并发场景时,通常采用多进程形式,尽量有效利用各个CPU核心。
在对于并行数目而言,也不一定是非得等于CPU核心数,对于CPU利用不足的情况,则可以适当考虑选择CPU核心倍数的进程(或者goroutine)。
然后关于异步的一点点想法,异步能够在高并发压力下缓解一部分来自于IO等的压力(等待时间),将压力转换到event loop中。但是对于并发压力并不大的情况而言,对于Python的线程切换成本会小于在事件循环的成本,所以在异步通常的应用场景一般是在IO密集场景之下。
上面是我的一点点想法,不知道是否正确,如果有什么理解错误或者根本概念错误,麻烦请详细的解惑一下或者提供一下相关资料学习,先提前致谢。