并发在于结构,并行在于执行
程序:本文所说的程序是指为了完成某个具体任务,而开发的一套软件,其微观动态上可以是(一组进程,多个线程,或者是一组协程执行体)
并行就是在任一粒度的时间内都具备同时执行的能力:最简单的并行就是多机,多台机器并行处理;SMP表面上看是并行的,但是由于是共享内存,以及线程间的同步等,不可能完全做到并行;
并发是在规定的时间粒度内多个请求都得到执行和处理,强调的是给人的感觉,实际可能是分时操作,重在避免阻塞,使程序不会因为一个阻塞而停止处理,最典型的应用场景就是:分时操作系统就是一种并发设计(忽略多核CPU);
在当前的计算机单机体系下:并行具有瞬时性,并发具有过程性;
在非计算密集型应用中,CPU的处理能力是非常出众的,CPU大都因为等待其他部件而阻塞,(磁盘,网络,其他设备);此时为了发挥CPU的运行效率,就需要将一个大程序拆分为多个执行体(多线程,多进程),最大限度的发挥
CPU的处理能力,提高程序吞吐量,这也是多线程,多进程编程的最大目的。
并发强调的是程序的设计粒度,粒度小,调度快,给人在感觉上同时处理(避免阻塞,等待时间短);
程序在运行中可能遇到各种等待,等待IO操作,所以在设计程序结构时,将其设计成多个执行体,一个执行体阻塞,其他执行体能正常运行;
实现并发的技术有多种:多进程消息队列,多线程,协程(go的goroutine并发设计理念,当然多个goroutine的通信和锁机制是另一个主题);
协程一般需要软件库支持或者语言层面的支持,在用户态再做一层调度,协程是更小用户态的执行体,可以有成千上万,底层支撑是多线程来执行,最复杂的就是支撑调度的运行时(golang是在语言层面解决,程序员简单实用go就可以,调度完全是语言运行时去解决)。
并行就是同时处理,其属于更底层的东西,一般是CPU和操作系统开发者需要着重考虑的问题:CPU功耗,CPU调度和负载平衡等等;
作为普通的程序员,唯一可以选择的就是充分借助OS提供的接口结合实际需求合理设计程序(常见的高性能编程模式:多进程,多线程,协程(用户态线程调度));
#线程数量选择:
如果所有的任务都是计算密集型的,此时系统上跑的内核线程数和CPU核心数保持一致,能最大限度的发挥CPU的优势;
如果任务是IO密集型的任务,我们可以开辟更多的线程执行任务;当一个任务执行IO操作的时候,线程将会被阻塞,处理器立刻会切换到另外一个合适的线程去执行。
#默认如果不是在裸机上写程序,某人说自己写并行程序,其实是在扯淡,隔着一层OS,程序员不能控制CPU的并行执行,其只能委托给OS去处理,实际上大多数程序员只能通过OS提供的特性来提升程序并发处理能力,OS提供的往往都是多线程,多进程模型;当然高级语言的运行时提供用户态协程;
Linux之父Linus都认为并行计算基本上就是浪费大家的时间,可见并行编程领域充满分歧和争议。
版权声明:本文为博主原创文章,未经博主允许不得转载。