多任务的实现方式——“多进程”与“多线程”

1 多任务

  • 单任务:一个函数或者方法执行完成另外一个函数或者方法才能执行

  • 多任务:指在同一时间内执行多个任务(任务可以是函数或者方法),例如: 现在电脑安装的操作系统都是多任务操作系统,可以同时运行着多个软件。

  • 多任务的最大好处:充分利用CPU资源,提高程序的执行效率。

  • 多任务的执行方式:并发和并行
    (1)并发:在一段时间内交替去执行任务。
    例如:对于单核cpu处理多任务,操作系统轮流让各个软件交替执行,假如:软件1执行0.01秒,切换到软件2,软件2执行0.01秒,再切换到软件3,执行0.01秒……这样反复执行下去。表面上看,每个软件都是交替执行的,但是,由于CPU的执行速度实在是太快了,我们感觉就像这些软件都在同时执行一样,这里需要注意单核cpu是并发的执行多任务的。
    (2)并行:多个任务真正意义上一起执行。
    对于多核cpu处理多任务,操作系统会给cpu的每个内核安排一个执行的软件,多个内核是真正的一起执行软件。这里需要注意多核cpu是并行的执行多任务,始终有多个软件一起执行。

  • 多任务的实现方式:多进程与多线程

2 多进程与多线程

2.1 进程

  • 进程:操作系统进行资源分配的基本单位
    一个正在运行的程序或者软件就是一个进程,每启动一个进程,操作系统都会给其分配一定的运行资源(内存资源)保证进程的运行。
    比如:现实生活中的公司可以理解成是一个进程,公司提供办公资源(电脑、办公桌椅等),真正干活的是员工,员工可以理解成线程。
  • 多进程可以完成多任务,每个进程就好比一家独立的公司,每个公司都各自在运营,每个进程也各自在运行,执行各自的任务。
  • 进程之间不共享全局变量
    创建子进程会对主进程资源进行拷贝,也就是说子进程是主进程的一个副本,好比是一对双胞胎,之所以进程之间不共享全局变量,是因为操作的不是同一个进程里面的全局变量,只不过不同进程里面的全局变量名字相同而已。
  • 主进程会等待所有的子进程执行结束再结束
    • 假如我们就让主进程执行0.5秒钟,子进程就销毁不再执行,那怎么办呢?
      我们可以设置守护主进程 或者 在主进程退出之前 让子进程销毁。为了保证子进程能够正常的运行,主进程会等所有的子进程执行完成以后再销毁,设置守护主进程的目的是主进程退出子进程销毁,不让主进程再等待子进程去执行。

2.2 线程

  • 线程:cpu调度的基本单位
    线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程。
  • 程序启动默认会有一个主线程,程序员自己创建的线程称为子线程,多线程可以完成多任务。
  • 线程之间执行是无序的
  • 主线程会等待所有的子线程执行结束再结束
    • 假如我们就让主线程执行1秒钟,子线程就销毁不再执行,那怎么办呢?
      我们可以设置守护主线程
  • 线程之间共享全局变量
  • 线程之间共享全局变量数据出现错误问题
    • 全局变量数据错误的解决办法:
      线程同步: 保证同一时刻只能有一个线程去操作全局变量 同步: 就是协同步调,按预定的先后次序进行运行。如:你说完,我再说, 好比现实生活中的对讲机
      线程同步的方式:(1)线程等待(join)、(2)互斥锁
  • 互斥锁: 对共享数据进行锁定,保证同一时刻只能有一个线程去操作。
    互斥锁是多个线程一起去抢,抢到锁的线程先执行,没有抢到锁的线程需要等待,等互斥锁使用完释放后,其它等待的线程再去抢这个锁。
    互斥锁的作用:保证同一时刻只能有一个线程去操作共享数据,保证共享数据不会出现错误问题
    互斥锁的好处:确保某段关键代码只能由一个线程从头到尾完整地去执行
    互斥锁的坏处:会影响代码的执行效率,多任务改成了单任务执行
    互斥锁如果没有使用好容易出现死锁的情况(一般是因为没有正确上锁和解锁)
    • 死锁: 一直等待对方释放锁的情景就是死锁。会造成应用程序的停止响应,不能再处理其它任务了。

3 进程和线程的对比

进程和线程都是完成多任务的一种方式

3.1 关系对比

线程是依附在进程里面的,没有进程就没有线程。
一个程序运行后至少有一个进程,一个进程默认提供一条线程,进程可以创建多个线程。
多任务的实现方式——“多进程”与“多线程”

3.2 区别对比

  1. 进程之间不共享全局变量
    线程之间共享全局变量,但是要注意资源竞争的问题,解决办法: 互斥锁或者线程同步
  2. 创建进程的资源开销要比创建线程的资源开销要大
  3. 进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
    • 线程之间执行是无序的,它是由cpu调度决定的 ,cpu调度哪个线程,哪个线程就先执行,没有调度的线程不能执行。
    • 进程之间执行也是无序的,它是由操作系统调度决定的,操作系统调度哪个进程,哪个进程就先执行,没有调度的进程不能执行。
  4. 线程不能够独立执行,必须依存在进程中
  5. 多进程开发比单进程多线程开发稳定性要强(某个进程挂掉不会影响其它进程)
  6. 多进程可以使用cpu的多核运行,多线程可以共享全局变量

3.3 优缺点对比

  • 进程优缺点:
    优点:可以用多核
    缺点:资源开销大
  • 线程优缺点:
    优点:资源开销小
    缺点:不能使用多核