Subprocess 和 Multiprocessing 的区别与使用要点及进程关闭方法

Subprocess 和 Multiprocessing 的区别与使用要点及进程关闭方法

最近在使用这两个库比较多,所以就借此机会记录一下这两个库的使用方式

一、Subprocess 和 Multiprocessing 的区别

1. 功能目标不同

  • Subprocess:主要用于在 Python 程序中启动外部程序或命令,并与它们进行交互,管理其输入、输出和错误流。例如,可以调用系统命令行工具来执行特定任务,如文件操作、系统管理等。

  • Multiprocessing:旨在利用多核处理器的优势,通过创建多个独立的 Python 进程来并行执行任务,提高程序的性能和效率。主要用于处理可以并行化的计算密集型任务或需要独立执行的多个任务。

2. 进程管理方式不同

  • Subprocess:管理的是外部进程,对这些进程的控制相对有限。主要关注启动进程、传递参数、捕获输出和处理错误等操作。一旦启动了外部进程,通常只能等待它完成或通过特定的信号进行交互。

  • Multiprocessing:提供了更全面的进程管理功能,可以创建、启动、停止和同步多个 Python 进程。可以在主程序中控制子进程的生命周期,并且可以通过共享数据结构或消息传递机制在进程之间进行通信。

二、Subprocess 的使用知识点

1. 启动外部命令

使用 subprocess.run() 函数可以方便地启动外部命令,并获取其返回码、输出和错误信息。例如:

md-end-block 复制代码
import subprocess

result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print(result.stdout)

这里执行了 ls -l 命令,并打印出其输出。

2. 管道和重定向

可以使用 subprocess.Popen() 来创建更复杂的管道和重定向操作。例如:

md-end-block 复制代码
p1 = subprocess.Popen(["ls"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "txt"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
output = p2.communicate()[0]
print(output.decode())

这个例子中,首先执行 ls 命令,然后将其输出通过管道传递给 grep 命令进行过滤。

3. 错误处理

当外部命令执行出错时,可以通过检查返回码和错误信息来进行处理。例如:

md-end-block 复制代码
result = subprocess.run(["invalid_command"], capture_output=True, text=True)
if result.returncode!= 0:
    print(f"Error: {result.stderr}")

三、Multiprocessing 的使用知识点

1. 创建进程

可以使用 multiprocessing.Process 类来创建一个新的进程。例如:

md-end-block 复制代码
import multiprocessing

def worker():
    print("Worker process is running.")

if __name__ == '__main__':
    process = multiprocessing.Process(target=worker)
    process.start()

这里定义了一个 worker 函数,并在主程序中创建了一个新的进程来执行这个函数。

2. 进程间通信

  • 共享内存 :可以使用 multiprocessing.Valuemultiprocessing.Array 来创建共享的内存对象,以便在进程之间共享数据。例如:
md-end-block 复制代码
import multiprocessing

shared_value = multiprocessing.Value('i', 0)

def increment():
    global shared_value
    with shared_value.get_lock():
        shared_value.value += 1

processes = [multiprocessing.Process(target=increment) for _ in range(10)]
for p in processes:
    p.start()
for p in processes:
    p.join()

print(shared_value.value)
  • 消息传递 :可以使用 multiprocessing.Queuemultiprocessing.Pipe 来实现进程间的消息传递。例如:
md-end-block 复制代码
import multiprocessing

def producer(q):
    for i in range(10):
        q.put(i)

def consumer(q):
    while True:
        item = q.get()
        if item is None:
            break
        print(item)

if __name__ == '__main__':
    q = multiprocessing.Queue()
    p1 = multiprocessing.Process(target=producer, args=(q,))
    p2 = multiprocessing.Process(target=consumer, args=(q,))
    p1.start()
    p2.start()
    p1.join()
    q.put(None)
    p2.join()

3. 进程池

multiprocessing.Pool 可以方便地管理多个进程,自动分配任务并收集结果。例如:

md-end-block 复制代码
import multiprocessing

def square(x):
    return x * x

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(square, range(10))
    print(results)

四、关闭进程的方法

对于 Subprocess 创建的进程

  • 等待进程自然结束:可以使用 subprocess.run()subprocess.Popen().wait() 来等待外部进程自然结束。如果外部进程无限期运行,可以考虑设置超时时间或通过发送特定信号来终止它。

  • 发送信号终止进程:可以使用 subprocess.Popen().terminate()subprocess.Popen().kill() 来发送终止信号给外部进程。terminate() 通常发送一个温和的终止信号(SIGTERM),而 kill() 发送一个强制终止信号(SIGKILL)。

对于 Multiprocessing 创建的进程

  • 使用 Process.terminate():可以在主程序中调用子进程对象的 terminate() 方法来立即终止子进程。例如:
md-end-block 复制代码
import multiprocessing

def worker():
    while True:
        pass

if __name__ == '__main__':
    process = multiprocessing.Process(target=worker)
    process.start()
    # 某个条件满足时终止子进程
    process.terminate()
    process.join()
  • 使用 Pool.terminate():如果使用了进程池,可以调用 Pool.terminate() 来立即终止所有正在运行的子进程。例如:
md-end-block 复制代码
import multiprocessing

def square(x):
    return x * x

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        # 某个条件满足时终止进程池中的所有进程
        pool.terminate()
相关推荐
ZH15455891314 分钟前
Flutter for OpenHarmony Python学习助手实战:面向对象编程实战的实现
python·学习·flutter
玄同7655 分钟前
SQLite + LLM:大模型应用落地的轻量级数据存储方案
jvm·数据库·人工智能·python·语言模型·sqlite·知识图谱
User_芊芊君子10 分钟前
CANN010:PyASC Python编程接口—简化AI算子开发的Python框架
开发语言·人工智能·python
白日做梦Q21 分钟前
Anchor-free检测器全解析:CenterNet vs FCOS
python·深度学习·神经网络·目标检测·机器学习
喵手35 分钟前
Python爬虫实战:公共自行车站点智能采集系统 - 从零构建生产级爬虫的完整实战(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集公共自行车站点·公共自行车站点智能采集系统·采集公共自行车站点导出csv
喵手42 分钟前
Python爬虫实战:地图 POI + 行政区反查实战 - 商圈热力数据准备完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·地区poi·行政区反查·商圈热力数据采集
熊猫_豆豆1 小时前
YOLOP车道检测
人工智能·python·算法
nimadan121 小时前
**热门短剧小说扫榜工具2025推荐,精准捕捉爆款趋势与流量
人工智能·python
默默前行的虫虫1 小时前
MQTT.fx实际操作
python
YMWM_1 小时前
python3继承使用
开发语言·python