[Python进阶] 进程与线程

9.1 进程与线程

9.1.1 进程和线程介绍

在Windows操作系统中,进程和线程都是操作系统所运行的程序运行的基本单元。
进程资源分配的基本单位,它拥有独立的地址空间系统资源,是计算机中运行应用程序的实体。每个进程都有自己的内存空间和系统资源,并且只能通过系统分配的地址空间进行访问。当一个进程崩溃时,它对其它进程不会产生影响,因为每个进程都运行在自己的地址空间中。
线程是CPU独立运行和独立调度的基本单位,是进程中的一段序列,能够完成进程中的一个功能。一个进程可以包含多个线程,而一个线程只能存在于一个进程中。同一个进程下的所有线程能够共享该进程下的资源,这意味着线程之间可以相互通信并访问共享数据。然而,一个线程的结束不会影响同一进程下的其他线程,因为每个线程都有自己的局部变量
线程是轻量级的进程,它的创建和销毁所需要的时间比进程小得多。由于线程的创建和销毁成本较低,因此在需要进行频繁创建和销毁的场景下,使用线程通常会比使用进程更高效。
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程
进程是资源分配的最小单位,线程是CPU调度的最小单位。
总的来说,进程和线程都是操作系统中重要的概念。它们之间的主要区别在于进程具有独立的地址空间和系统资源,而线程则是轻量级且共享进程资源的执行序列。进程和线程的联系在于它们都是操作系统所运行的程序运行的基本单元,并且相互依存。

9.1.2 进程和线程区别

进程是资源分配的基本单位。所有与该进程有关的资源,都被记录在进程控制块PCB中。以表示该进程拥有这些资源或正在使用它们。
另外,进程也是抢占处理机的调度单位,它拥有一个完整的虚拟地址空间。当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。
线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。线程只由相关堆栈(系统栈或用户栈)寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其他线程的相关变量。
通常在一个进程中可以包含若干个线程,它们可以利用进程所拥有的资源。由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度,从而显著提高系统资源的利用率和吞吐量。因而近年来推出的通用操作系统都引入了线程,以便进一步提高系统的并发性,并把它视为现代操作系统的一个重要指标。
以下是进程和线程之间的区别对比表:

对比维度 多进程 多线程 总结
数据共享、同步 数据共享复杂,同步简单 数据共享简单,同步复杂 各有优劣
内存、CPU 占用内存多,切换复杂,CPU利用率低 占用内存少,切换简单,CPU利用率高 线程占优
创建、销毁、切换 复杂,速度慢 简单,速度快 线程占优
编程、调试 编程简单,调试简单 编程复杂,调试复杂 进程占优
可靠性 进程间不会互相影响 一个线程挂掉将导致整个进程挂掉 进程占优
分布式 适用于多核、多机,扩展到多台机器简单 适合于多核 进程占优

主进程下的子进程pid号不一样,但是子线程pid号一样,只要子进程没有退出,那么主进程的pid会一直存在。如下:

import time
from threading import Thread
from multiprocessing import Process
import os


def work():
    time.sleep(1)
    print('hello', os.getpid())


if __name__ == '__main__':
    print('part1:在主进程下开启多个线程,每个线程都跟主进程的pid一样')
    t1 = Thread(target=work)  # 创建线程
    t2 = Thread(target=work)
    t1.start()
    t2.start()
    print('主线程/主进程pid', os.getpid())
    time.sleep(2)
    print('part2:开多个进程,每个进程都有不同的pid')
    p1 = Process(target=work)  # 创建进程
    p2 = Process(target=work)
    p1.start()
    p2.start()
    print('主线程/主进程pid', os.getpid())

part1:在主进程下开启多个线程,每个线程都跟主进程的pid一样
主线程/主进程pid 13036
hellohello 13036
13036
part2:开多个进程,每个进程都有不同的pid
主线程/主进程pid 13036
hello 18904
hello 660

9.1.3 关于进程和线程的比喻

进程:火车
线程:车厢

  1. 线程在进程下运行,线程必须依赖于进程。(单纯的车厢无法运行,必须依赖于火车)
  2. 一个进程可以包含多个线程。(一辆火车可以有多节车厢)
  3. 不同进程间数据很难共享(一辆火车上的乘客很难到另外一辆火车上)
  4. 同一进程下不同线程间数据很易共享(同一辆火车乘客从车厢A换到车厢B很容易)
  5. 进程要比线程消耗更多的计算机资源(多辆火车运输乘客相比多个车厢更耗资源)
  6. 进程间不会相互影响,一个线程挂掉将导致整个进程挂掉(不同轨道上的火车不会互相影响,但是如果一辆火车上中间的一节车厢着火了,将影响到该火车的所有车厢)
  7. 进程可以拓展到多机,进程最多适合多核(不同火车可以开在多个轨道上,同一辆火车的车厢不能在行进的不同的轨道上)
  8. 进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。这就是互斥锁。(某一节车厢的洗手间)
  9. 进程使用的内存地址可以限定使用量(火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)

你可能感兴趣的:(Python进阶,#,九,并发编程,python,Python进阶,进程,线程)