多线程和多进程

2020 / 03 / 05

进程和线程

进程是操作系统中最核心的概念,现代操作系统的大多数系统都是围绕进程展开的,进程是进行中的程序的抽象,一个程序要同时占用很多不同的资源,文件系统,内存或者子进程,这些集合被称为进程,那为什么要再加一个线程的概念呢。

线程是进程的一个子概念,线程之间可以互相共享进程所占用的地址空间和可用数据。线程比进程开销更低,低10-100倍,所以可以非常快速的创建可以互相共享数据的线程,而进程的创建和通信的开销都要大很多。线程在进程的作用和进程在进程在计算机中的作用很相似,他允许进程的工作内容间存在较大的独立性。

线程可以用来优化性能,这首先需要知道计算机的CPU工作原理,一般来说CPU处理多个进程并不是一个处理结束再处理另一个,而是每个花几十毫秒或者几百毫秒处理一下,这样就给用户一种同时在做多件事情的错觉。这就像人脑一样,一个人要想同时做多件事情只能不停的切换,而不是大脑同时运算多个事情需要的解决方法。当然多核心的CPU是真的可以同时做多件事情的。

CPU密集型和IO密集型

CPU密集型会进行大量的计算,IO密集型会进行大量的读写,这个有什么区别呢,读写的时候更多的时候需要的是等待资源的写入和读取,这个时候内存和磁盘的工作速度要远比CPU低,所以执行代码的时候经常CPU利用率很低,内存和磁盘可能已经利用率非常高了,IO密集型的任务可以理解为体力活,大脑一直比较悠闲。CPU密集型的任务是脑力活,比如计算圆周率,计算小数点后10000位是非常占用CPU的事情,而内存和磁盘的占用却非常少,就像一个躺着不动只需要借助手指稍微记一下东西的人。

单线程还是多线程

明白了进程和线程的区别以及CPU密集型和IO密集型的区别之后,再看线程的用处。

首先还是运算圆周率后边1000位,那么用多个线程执行,就会是A线程运算了一会之后,交给B线程,然后再交给C线程,因为他不能同时运算第1位到100位和第100位到200位,只能挨着运算,这个过程里除了给CPU增加额外的切换线程的开销之外貌似没有任何好处。

如果是同时运算圆周率后1000位,和根号2的小数点的时候,假如是单核心的CPU那么依然需要把一件事做完再做另外一件事,而假如是多核心的CPU,A CPU过来开始执行运算圆周率,B CPU过来发现A再忙就去运算开根号了。所以再进行CPU密集型的处理的时候,线程数量最多等于CPU核心数,线程再多就没什么好处了。其实这种事情多进程可能会更好一些,假如过两个CPU用的是同一块内存,那么可能会发生竞争,所以多线程和多进程相比,多线程更像是平面交通系统,有红绿灯,有人行道,而多进程像是高架桥,不同的进程互不干扰的同时跑。

如果是做IO密集型的时候,比如要计算100道乘法运算,并且把结果写到100个文件里,这个时候即便在单核心CPU上也能有很大的好处,因为CPU运算每道题可能只需要0.00001ms,但是写文件却可能需要1ms,所以每个CPU运算完了就交给硬盘和内存写文件去了,自己去运算下一道题,这个事情放到单线程中就会变成运算一道题,写一道题,然后再运算下一道,很明显,多线程可以节省大量CPU运算时间。

Node是单线程么

那么node是单线程的,为什么可以高并发呢,其实node.js非常适合处理IO密集型的任务,比如网络请求,文件处理,而且它并不是单线程的,如果有高并发的网络请求或者文件处理,node就能发挥出非常强大的能力,比如上边举例的100次简单的运算却写入100个文件。所以node执行其实是单线程的,处理多IO的高并发任务很有优势。而在做CPU密集型的任务时却很吃力,当然现在node最近已经开始支持多线程了。

多进程不好么

每个进程都会至少有一个线程,所以多进程也相当于多线程,而且隔离的更好,不会出现堵车的现象,但是多进程之间通信复杂,共享能力也相对差一些,重点是更贵。当然为了交通效率更高还是要修一些高架桥的。


什么是CPU密集型、IO密集型?

Node.js 单线程为什么能支持高并发?

写评论
全部评论