首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python并发编程利器:threading模块及高阶应用

在现代计算机程序中,并发执行多个任务变得越来越重要。Python的threading模块为我们提供了在单个进程中创建和管理线程的能力,从而实现并发执行。本文将从threading模块的基本概念入手,逐步深入到更高层的线程接口,帮助大家更好地理解和应用Python的并发编程。

「什么是线程?」

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程实际运作的基本单位。一个进程可以包含多个线程,它们共享进程的内存空间和系统资源。相比于进程,线程的创建和切换开销更小,因此在需要频繁切换执行任务的场景下,使用线程可以提高程序的效率。

「threading模块基础」

threading模块是Python标准库中用于创建和管理线程的模块。下面是一些常用的类和方法:

Thread类:用于创建新的线程。

start()方法:启动线程。

join()方法:等待线程执行结束。

「示例1:创建和启动线程」

import threading

import time

def task(name):

  print(f"线程 {name} 开始执行")

  time.sleep(2)  # 模拟耗时操作

  print(f"线程 {name} 执行结束")

if __name__ == "__main__":

  thread1 = threading.Thread(target=task, args=("线程1",))

  thread2 = threading.Thread(target=task, args=("线程2",))

  thread1.start()

  thread2.start()

  thread1.join()

  thread2.join()

  print("所有线程执行完毕")

在这个例子中,我们创建了两个线程,分别执行task函数。args参数用于传递参数给task函数。join()方法确保主线程等待所有子线程执行完毕后再继续执行。

「线程同步与锁」

由于多个线程共享进程的内存空间,因此在访问共享资源时可能会出现竞争条件,导致数据不一致。为了解决这个问题,我们需要使用线程同步机制,例如锁。

threading模块提供了Lock类来实现锁的功能。

「示例2:使用锁保护共享资源」

import threading

import time

counter = 0

lock = threading.Lock()

def increment():

  global counter

  for _ in range(1000000):

      with lock:  # 获取锁

          counter += 1# 临界区

      # 释放锁(with语句会自动释放)

if __name__ == "__main__":

  thread1 = threading.Thread(target=increment)

  thread2 = threading.Thread(target=increment)

  thread1.start()

  thread2.start()

  thread1.join()

  thread2.join()

  print(f"counter = {counter}")

在这个例子中,我们使用Lock对象lock来保护共享变量counter。with lock:语句会自动获取和释放锁,确保在同一时间只有一个线程可以访问counter,从而避免了竞争条件。

「更高层的线程接口:concurrent.futures」

concurrent.futures模块提供了更高层的接口来管理线程和进程,使得并发编程更加简单和方便。其中,ThreadPoolExecutor类用于管理线程池。

「示例3:使用ThreadPoolExecutor」

import concurrent.futures

import time

def task(n):

  time.sleep(1)

  return n * n

if __name__ == "__main__":

  with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor: # 创建一个最多3个线程的线程池

      futures = [executor.submit(task, i) for i in range(5)] # 提交5个任务到线程池

      for future in concurrent.futures.as_completed(futures): # 遍历已完成的任务

          print(future.result()) # 获取任务的结果

在这个例子中,我们使用ThreadPoolExecutor创建了一个线程池,并将多个任务提交到线程池中执行。as_completed()函数可以按完成的顺序返回Future对象,我们可以通过result()方法获取任务的结果。

threading模块是Python并发编程的重要工具。通过本文的介绍,我们学习了threading模块的基本概念、线程的创建和管理、线程同步以及更高层的线程接口concurrent.futures。希望这些知识能够帮助初级工程师更好地理解和应用Python的并发编程,写出更高效的程序。

「进一步学习」

深入理解GIL(全局解释器锁):了解GIL对Python多线程的影响。

使用其他同步原语:例如RLock(可重入锁)、Condition(条件变量)、Semaphore(信号量)等。

学习multiprocessing模块:了解如何使用多进程实现真正的并行。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/O0yLdPWv8nlkkubiKT3-cWrQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券