python高阶应用——进程和线程

本文详细介绍了Python中线程管理(threading模块)和进程管理(multiprocessing模块)的基本概念、创建、同步、通信以及在实际场景中的应用,特别强调了GIL对CPU密集型任务的影响和多线程/I/O密集型任务的适用性。
摘要由CSDN通过智能技术生成

在 Python 中学习和管理线程与进程涉及对 threadingmultiprocessing 模块的理解和应用。下面是这两个模块的基础知识和使用方法。

线程管理(threading 模块)

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。在 Python 中,threading 模块提供了基本的线程操作接口。

1.创建线程

使用 threading.Thread 类创建一个线程对象,传入一个可调用的对象作为 target 参数,这个对象将在新线程中运行。

import threading
import time

def print_numbers(n):
    for i in range(n):
        time.sleep(1)
        print(i)

# 创建线程
thread = threading.Thread(target=print_numbers,args=5)
# 启动线程
thread.start()

# 等待线程完成
thread.join()
print("线程结束")

2.线程同步

由于线程间共享进程的内存,因此当多个线程要访问同一数据时,需要进行同步,以避免竞态条件。threading 模块提供了多种同步原语,如 Lock、Event、Condition、Semaphore 等。

# 使用 Lock 进行线程同步
lock = threading.Lock()

def thread_function(name):
    lock.acquire()
    try:
        print(f"Thread {name}: starting")
    finally:
        lock.release()

# 创建线程时使用同一个 lock 对象

进程管理(multiprocessing 模块)

进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。

1.创建进程

multiprocessing 模块提供了一个 Process 类来代表一个进程对象。创建和启动进程的方式与线程类似。

from multiprocessing import Process
import time

def print_numbers(n):
    for i in range(n):
        time.sleep(1)
        print(i)

# 创建进程
process = Process(target=print_numbers,args=5)
# 启动进程
process.start()

# 等待进程结束
process.join()
print("进程结束")

2.进程间通信

进程间通信可以通过 QueuePipe 实现。这些对象允许数据在进程之间传输。

from multiprocessing import Process, Queue

def process_function(q):
    q.put("Hello from child process")

q = Queue()
p = Process(target=process_function, args=(q,))
p.start()
print(q.get())  # 从队列中获取消息
p.join()
3.进程池

当需要创建和管理多个进程时,可以使用进程池来更方便地管理这些进程。

from multiprocessing import Pool

def pool_function(name):
    print(f"Process {name}: starting")

with Pool(5) as p:  # 创建包含5个进程的池
    p.map(pool_function, range(5))

多线程和多进程的实际场景

在 Python 中实现并行计算时,多进程由于可以绕过全局解释器锁(GIL)通常更适合 CPU 密集型任务。多线程在 Python 中由于 GIL 的存在,在执行 CPU 密集型任务时通常不会提供太多的性能提升,但它们在执行 I/O 密集型任务时仍然很有用。

1.实现并行下载 (I/O密集型)

为了实现并行下载,你可以使用 Python 的 threading 模块来创建多线程程序,或者使用 multiprocessing 模块来创建多进程程序。下面是分别使用这两种方法来实现并行下载文件的简单例子。

使用多线程实现并行下载
import threading
import requests

def download_file(url, filename):
    response = requests.get(url)
    with open(filename, 'wb') as file:
        file.write(response.content)
    print(f"{filename} downloaded.")

# 定义要下载的文件列表
urls = [
    "http://example.com/file1.zip",
    "http://example.com/file2.zip",
    # 更多文件 ...
]

# 创建并启动线程
threads = []
for i, url in enumerate(urls):
    filename = f"file_{i+1}.zip"
    thread = threading.Thread(target=download_file, args=(url, filename))
    thread.start()
    threads.append(thread)

# 等待所有线程完成
for thread in threads:
    thread.join()

print("All files downloaded.")
使用多进程实现并行下载
from multiprocessing import Process
import requests

def download_file(url, filename):
    response = requests.get(url)
    with open(filename, 'wb') as file:
        file.write(response.content)
    print(f"{filename} downloaded.")

# 定义要下载的文件列表
urls = [
    "http://example.com/file1.zip",
    "http://example.com/file2.zip",
    # 更多文件 ...
]

# 创建并启动进程
processes = []
for i, url in enumerate(urls):
    filename = f"file_{i+1}.zip"
    process = Process(target=download_file, args=(url, filename))
    process.start()
    processes.append(process)

# 等待所有进程完成
for process in processes:
    process.join()

print("All files downloaded.")

2.多线程和多进程实现并行计算 (CPU密集型)

使用多进程进行并行计算

from multiprocessing import Pool

# 定义一个 CPU 密集型任务函数
def cpu_intensive_task(n):
    return sum(i*i for i in range(n))

# 创建进程池
with Pool() as pool:
    # 使用 map 方法来分配任务到各个进程
    results = pool.map(cpu_intensive_task, [1000000, 2000000, 3000000, 4000000])

# 打印结果
for result in results:
    print(result)

使用多线程进行并行计算

虽然通常不推荐使用多线程进行 CPU 密集型计算,但为了展示如何使用,下面是一个多线程的示例。

from threading import Thread

# 定义一个 CPU 密集型任务函数
def cpu_intensive_task(n):
    print(sum(i*i for i in range(n)))

# 创建线程
threads = []
for n in [1000000, 2000000, 3000000, 4000000]:
    thread = Thread(target=cpu_intensive_task, args=(n,))
    thread.start()
    threads.append(thread)

# 等待所有线程完成
for thread in threads:
    thread.join()

在实际应用中:
在 CPU 密集型任务中,由于 Python 的 GIL(全局解释器锁),多线程不一定能在 CPU 密集型任务中提供性能上的提升,而多进程由于可以绕过 GIL,通常能提供更好的性能提升,它们可以在多核处理器上实现真正的并行计算。
而对于 I/O 密集型任务,多线程和多进程都可以提高效率,但多线程通常更轻量级,创建和切换的开销更小。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值