在 Python 中,进程和线程是实现并发编程的两种重要方式,下面将详细介绍它们的概念、实例以及各自常用的方法。
进程(Process)
概念
进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。每个进程都有自己独立的内存空间、系统资源和执行上下文,进程之间相互独立,一个进程的崩溃不会影响其他进程。
实例
使用 Python 的 multiprocessing
模块可以创建和管理进程。以下是一个简单的示例:
import multiprocessingdef worker(num):"""进程要执行的任务"""print(f'Worker {num} started')result = num * numprint(f'Worker {num} result: {result}')print(f'Worker {num} finished')if __name__ == '__main__':processes = []for i in range(3):p = multiprocessing.Process(target=worker, args=(i,))processes.append(p)p.start()for p in processes:p.join()print('All processes finished')
代码解释
multiprocessing.Process
:用于创建一个新的进程对象,target
参数指定进程要执行的函数,args
参数是传递给该函数的参数。p.start()
:启动进程,使其开始执行target
函数。p.join()
:等待进程执行完毕,确保主进程在所有子进程执行完后再继续执行。
常用方法
start()
:启动进程,让进程开始执行其目标函数。join([timeout])
:等待进程结束,如果指定了timeout
,则最多等待timeout
秒。terminate()
:强制终止进程,在 Unix 系统中使用SIGTERM
信号,在 Windows 系统中使用TerminateProcess
函数。is_alive()
:检查进程是否还在运行,返回布尔值。name
:进程的名称,可以通过设置该属性来为进程命名。pid
:进程的 ID,可以通过该属性获取进程的唯一标识符。
线程(Thread)
概念
线程是进程中的一个执行单元,一个进程可以包含多个线程。线程共享进程的内存空间和系统资源,它们可以并发执行,提高程序的执行效率。但由于线程共享资源,需要注意线程安全问题,避免出现数据竞争和不一致的情况。
实例
使用 Python 的 threading
模块可以创建和管理线程。以下是一个简单的示例:
import threadingdef worker(num):"""线程要执行的任务"""print(f'Thread {num} started')result = num * numprint(f'Thread {num} result: {result}')print(f'Thread {num} finished')if __name__ == '__main__':threads = []for i in range(3):t = threading.Thread(target=worker, args=(i,))threads.append(t)t.start()for t in threads:t.join()print('All threads finished')
代码解释
threading.Thread
:用于创建一个新的线程对象,target
参数指定线程要执行的函数,args
参数是传递给该函数的参数。t.start()
:启动线程,使其开始执行target
函数。t.join()
:等待线程执行完毕,确保主线程在所有子线程执行完后再继续执行。
常用方法
start()
:启动线程,让线程开始执行其目标函数。join([timeout])
:等待线程结束,如果指定了timeout
,则最多等待timeout
秒。is_alive()
:检查线程是否还在运行,返回布尔值。name
:线程的名称,可以通过设置该属性来为线程命名。setDaemon(daemonic)
:设置线程是否为守护线程,守护线程会在主线程退出时自动退出。daemon
:获取或设置线程的守护状态,布尔值。
进程和线程的比较
- 资源开销:进程的创建和销毁开销较大,因为每个进程都有自己独立的内存空间和系统资源;线程的创建和销毁开销相对较小,因为线程共享进程的资源。
- 并发性能:进程可以利用多核 CPU 的优势,实现真正的并行执行;线程由于共享资源,在单核 CPU 上主要是并发执行,在多核 CPU 上也可以实现一定程度的并行。
- 数据共享:进程之间的数据是独立的,需要通过进程间通信(IPC)机制(如管道、队列、共享内存等)来实现数据共享;线程之间共享进程的内存空间,可以直接访问和修改共享数据,但需要注意线程安全问题。
- 稳定性:进程之间相互独立,一个进程的崩溃不会影响其他进程;线程共享资源,一个线程的崩溃可能会导致整个进程崩溃。