一文带你入门 Python 的 threading 多线程

在 Python 编程领域,多线程是一项强大的技术,它允许程序同时执行多个任务,有效提升程序的运行效率与响应速度。threading模块作为 Python 标准库中用于多线程编程的利器,为开发者提供了简洁且易于理解的接口。接下来,就让我们一同踏入threading多线程的入门之旅。

一、为什么使用多线程

想象一下,你正在编写一个程序,它既要从网络上下载文件,又要实时更新用户界面。如果按顺序执行这些任务,下载文件时用户界面会冻结,用户体验极差。而多线程就能解决这个问题,它让下载和界面更新可以同时进行,大大提高了程序的流畅性和响应性。

二、创建简单线程

使用threading模块创建线程非常简单。以下是一个基本示例:

python

import threading


def print_numbers():
    for i in range(1, 6):
        print(f"线程1: {i}")


def print_letters():
    for letter in 'abcde':
        print(f"线程2: {letter}")


if __name__ == '__main__':
    thread1 = threading.Thread(target=print_numbers)
    thread2 = threading.Thread(target=print_letters)

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

在这个例子中:

  1. 我们定义了两个函数print_numbers和print_letters,这两个函数就是我们希望在线程中执行的任务。
  2. 通过threading.Thread类创建了两个线程对象thread1和thread2,并分别指定了它们要执行的目标函数。
  3. 使用start()方法启动线程,这会让线程开始执行目标函数。
  4. join()方法用于等待线程执行完毕。当一个线程调用join()时,主线程会阻塞,直到该线程完成任务。

三、线程传参

线程执行的函数常常需要传递参数。下面展示如何给线程函数传递参数:

python

import threading


def greet(name):
    print(f"你好, {name}!")


if __name__ == '__main__':
    thread = threading.Thread(target=greet, args=('Alice',))
    thread.start()
    thread.join()

这里通过args参数将'Alice'传递给greet函数。args是一个元组,即使只传递一个参数,也需要加上逗号以表明它是一个元组。

四、共享资源与锁

当多个线程同时访问和修改共享资源时,可能会引发数据不一致的问题。例如,多个线程同时对一个全局变量进行累加操作,可能会导致结果错误。为了解决这个问题,我们可以使用锁(Lock)。

python

import threading

counter = 0
lock = threading.Lock()


def increment():
    global counter
    for _ in range(1000000):
        with lock:
            counter += 1


if __name__ == '__main__':
    thread1 = threading.Thread(target=increment)
    thread2 = threading.Thread(target=increment)

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

    print(f"计数器的值: {counter}")

在这个示例中:

  1. 定义了一个全局变量counter作为共享资源,以及一个锁对象lock。
  2. 在increment函数中,使用with lock语句来获取锁。这确保了在同一时间只有一个线程能够进入这个代码块,对counter进行操作,从而避免了数据竞争问题。

五、线程同步

除了锁,threading模块还提供了其他同步机制,如事件(Event)。事件允许一个线程通知其他线程发生了某个事件。

python

import threading
import time


def worker(event):
    print("工作线程等待事件...")
    event.wait()
    print("工作线程接收到事件,开始工作...")


if __name__ == '__main__':
    event = threading.Event()
    thread = threading.Thread(target=worker, args=(event,))
    thread.start()

    time.sleep(2)
    print("主线程设置事件...")
    event.set()

    thread.join()

在这个例子中:

  1. 创建了一个Event对象event。
  2. 工作线程在event.wait()处阻塞,等待事件被设置。
  3. 主线程睡眠 2 秒后,调用event.set()设置事件,从而唤醒工作线程继续执行。
原文链接:,转发请注明来源!