python多进程

python多进程

多进程与多线程

(这一段是从网上找的,感觉写的非常好,借用一下!) 无论是多进程还是多线程,只要数量一多,效率肯定上不去,为什么呢?我们打个比方,假设你不幸正在准备中考,每天晚上需要做语文、数学、英语、物理、化学这5科的作业,每项作业耗时1小时。

如果你先花1小时做语文作业,做完了,再花1小时做数学作业,这样,依次全部做完,一共花5小时,这种方式称为单任务模型,或者批处理任务模型。 假设你打算切换到多任务模型,可以先做1分钟语文,再切换到数学作业,做1分钟,再切换到英语,以此类推,只要切换速度足够快,这种方式就和单核CPU执行多任务是一样的了,以幼儿园小朋友的眼光来看,你就正在同时写5科作业。

但是,切换作业是有代价的,比如从语文切到数学,要先收拾桌子上的语文书本、钢笔(这叫保存现场),然后,打开数学课本、找出圆规直尺(这叫准备新环境),才能开始做数学作业。操作系统在切换进程或者线程时也是一样的,它需要先保存当前执行的现场环境(CPU寄存器状态、内存页等),然后,把新任务的执行环境准备好(恢复上次的寄存器状态,切换内存页等),才能开始执行。这个切换过程虽然很快,但是也需要耗费时间。如果有几千个任务同时进行,操作系统可能就主要忙着切换任务,根本没有多少时间去执行任务了,这种情况最常见的就是硬盘狂响,点窗口无反应,系统处于假死状态。 所以,多任务一旦多到一个限度,就会消耗掉系统所有的资源,结果效率急剧下降,所有任务都做不好。

计算密集型 vs. IO密集型

是否采用多任务的第二个考虑是任务的类型。我们可以把任务分为计算密集型和IO密集型。

计算密集型任务的特点是要进行大量的计算,消耗CPU资源,比如计算圆周率、对视频进行高清解码等等,全靠CPU的运算能力。这种计算密集型任务虽然也可以用多任务完成,但是任务越多,花在任务切换的时间就越多,CPU执行任务的效率就越低,所以,要最高效地利用CPU,计算密集型任务同时进行的数量应当等于CPU的核心数。 计算密集型任务由于主要消耗CPU资源,因此,代码运行效率至关重要。Python这样的脚本语言运行效率很低,完全不适合计算密集型任务。对于计算密集型任务,最好用C语言编写。

第二种任务的类型是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。 IO密集型任务执行期间,99%的时间都花在IO上,花在CPU上的时间很少,因此,用运行速度极快的C语言替换用Python这样运行速度极低的脚本语言,完全无法提升运行效率。对于IO密集型任务,最合适的语言就是开发效率最高(代码量最少)的语言,脚本语言是首选,C语言最差。

并发, 并行, 线程,进程

  • 并发:指的是”任务数多余cpu核数”,通过操作系统的各种任务调度算法,实现⽤多个任务“⼀起”执⾏(实际上总有⼀些任务不在执⾏,因为切换任务的速度相当快,看上去⼀起执⾏⽽已)
  • 并⾏:指的是”任务数⼩于等于cpu核数”,即任务真的是⼀起执⾏的

  • 多线程(threading):
    • ①在”⼀个进程”内的所有线程共享全局变量,很⽅便在多个线程间共享数据
    • ②缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程⾮安全)

    • ③如果多个线程同时对同⼀个全局变量操作,会出现资源竞争问题,从⽽数据结果会不正确
  • 解决多线程同时修改全局变量的⽅式:互斥锁(互斥锁为资源引⼊⼀个状态:锁定/⾮锁定 某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他 线程不能更改;直到该线程释放资源,将资源的状态变成“⾮锁定”,其他的 线程才能再次锁定该资源。互斥锁保证了每次只有⼀个线程进⾏写⼊操作, 从⽽保证了多线程情况下数据的正确性。)
  • 多进程(multiprocessing):进程不共享全局变量如果子进程因为某种原因崩溃了,不会直接导致主程序的崩溃,可以降低主程序崩溃的概率; 即使主进程退出了,子进程仍然可以继续工作,比如子进程是推送服务,在主进程退出的情况下,仍然能够保证用户可以收到推送消息。

区别

  • 进程,能够完成多任务,⽐如在⼀台电脑上能够同时运⾏多个QQ
  • 线程,能够完成多任务,⽐如 ⼀个QQ中的多个聊天窗⼝
  • 线程不能够独⽴执⾏,必须依存在进程中。可以将进程理解为⼯⼚中的⼀条流⽔线,⽽其中的线程就是这个流⽔线 上的⼯⼈
  • 进程:是系统进⾏资源分配和调度的⼀个独⽴单位.
  • 线程:是进程的⼀个实体,是CPU调度和分派的基本单位,它是⽐进程更⼩的能独⽴运⾏的基本单位.线程⾃⼰基本上不拥有系统资源,只拥有⼀点在运  ⾏中必不可少的资源(如程序计数器,⼀组寄存器和栈),但是它可与同属⼀个进程的其他的线程共享进程所拥有的全部资源.

打赏,谢谢~~

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,多谢支持~

打开微信扫一扫,即可进行扫码打赏哦