【Python】进程和线程

一、进程

进程表示的是一个正在执行的程序,每个进程都拥有自己的地址空间、内存、数据栈,以及其他用于跟踪执行的辅助数据。操作系统负责所有进程的执行,操作系统会为这些进程合理地分配执行时间。

进程是程序的一次运行活动,属于一种动态的概念。程序是一组有序的静态指令,是一种静态的概念。但是,进程离开了程序也就没有了任何存在的意义。因此进程是执行程序的动态过程而程序是进程运行的静态文本。

1.进程的运行

进程需要使用一种机构才能执行程序,这种机构称之为处理机(processer)。处理机执行指令,根据指令的性质,处理机可以单独使用硬件或者软硬件结合起来构成。如果指令是机器指令,那么处理机一般就是我们说的中央处理器(CPU)。

只有一个CPU运行时,轮询调度实现并发执行:早期的计算机只具有一个中央处理器并且时单核,这种情况下计算机操作系统采用并发技术实现并发运行。

多个CPU运行机制:将多个核心装载一个封装里,使得多个程序可以并发运行。

一个进程还可以拥有多个并发的执行线索,简单来说就是拥有多个可以获得CPU调度的执行单元,这就是所谓的线程。

今天我们使用的软件几乎都用到了多线程技术,这一点可以利用系统自带的进程监控工具(如macOS中的“活动监视器”、Windows中的“任务管理器”)来证实,如下所示:

2.进程的创建方式

①使用Process子类创建进程

在windows操作系统中,muliprocessing模块提供了一个process类来代表一个进程对象。

②使用进程池pool创建进程

进程池就是实现已经创建好的进程,进程池里面放的都是进程,进程池可以根据任务自动创建进程,合理利用进程池中的进程完成多项任务。进程池更多的是优化了代码,可以多个进程不下载重复利用。

3.进程间通信的方式

①管道(PIPE)

管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程中使用。进程的亲缘关系是指父子进程关系

管道的原型:

#include <unistd.h>
int pipe(int fd[2]);

②命名管道(FIFO)

命名管道也是半双工的通信方式,但是它运行无亲缘关系进程间的通信。

命名管道的原型:

#include<sys/stat.h>
int mkififo(const char *pathname,mode_t  mode);

其中,mode参数与open函数中的mode相同。一旦创建了一个FIFO,就可以用一般的文件I/O函数操作它。

③消息队列(MessageQueue)

消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

④内存共享(ShareMemory)

内存共享就是映射一段时间被其他进程所访问的内存,这段内存共享由一个进程创建,但是多个进程都可以访问。内存共享是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门是假的。

共享内存的常用函数

函数功能
mmap建立共享内存映射
munmap解除共享内存映射
shmget获取共享内存区域的ID
shmat建立映射共享内存
shmdt解除内存共享映射

⑤信号量(Semaphore)

信号量是一个计数器,可以用来控制多个进程对资源共享的访问。它常常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。

【原子操作】:指不会被线程调度机制打断的操作,这种操作一旦开始,就会一直运行到结束,中间不会切换到其他进程。

二、线程

1.线程的基本概念

线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行过程中的最小单元,曲线程ID、程序计数器、寄存器集合和堆栈共同组成。

【说明】当一个进程里面只有一个线程时,叫做单线程;超过一个线程就叫做多线程。

2.线程的创建方式

在Python中,在有关线程开发的部分被单独封装到了模板中,和线程有关的模型有以下两个:

(1)-thread:Python3以前版本中thread模块的重命名,次模块提供了低级别的、原始的线程支持,以及一个简单的锁,功能比较有限,因此不建议使用thread模块

(2)threading:Python3之后的现场模块,提供了功能丰富的多线程支持,推荐使用。

3.线程间通信

一般而言,在一个应用程序中(即进程),一个线程往往不是孤立存在的,常常需要和其他线程通信,以执行特定的任务。例如,主线程和次线程,此线程和此线程,工作线和用户界面线程等。这样,线程与线程之间必定有一个信息传递的渠道。

在Windows中线程间的通信一般采用四肢方式:全局变量方式、参数传递方式、消息传递方式和线程同步法。

4.线程同步的方法

线程同步的集中方法,主要涉及thread和threading模块。

threading模块提供的线程同步原语包括:Lock、RLock、Condition、Event、Semaphore等对象。

### Python 进程线程应用示例 #### 使用 `threading` 模块实现多线程 为了展示如何利用 Python 的 `threading` 模块创建多个线程并行工作,下面给出了一段简单代码: ```python import threading import time def worker(num): """线程要执行的任务""" print(f"Worker {num} 开始") time.sleep(2) # 模拟耗时操作 print(f"Worker {num} 结束") if __name__ == '__main__': threads = [] for i in range(5): # 创建五个线程 t = threading.Thread(target=worker, args=(i,)) threads.append(t) t.start() for t in threads: # 等待所有线程完成 t.join() ``` 这段程序会启动五个独立运行的子线程去调用 `worker()` 函数,在这里通过睡眠模拟了一个耗时的操作[^1]。 #### 利用 `multiprocessing` 实现多进程 当面对 CPU 密集型任务时,由于存在 GIL 锁的影响,推荐采用多进程的方式。以下是使用 `multiprocessing` 来处理此类情况的例子: ```python from multiprocessing import Process, cpu_count import os def process_task(process_id): """每个进程中执行的任务""" print(f'Process ID: {process_id}, PID: {os.getpid()}') sum(range(10 ** 7)) # 计算密集型任务 if __name__ == '__main__': processes = [] num_processes = min(cpu_count(), 4) for i in range(num_processes): p = Process(target=process_task, args=(i,)) processes.append(p) p.start() for p in processes: p.join() ``` 此脚本将根据计算机上的可用核心数来决定开启多少个进程来进行大规模数据运算[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值