Python多线程使用方法详细讲解

yizhihongxing

Python多线程使用方法详细讲解

在 Python 中,多线程可以用于许多场景,比如爬虫、并行处理等。本文将详细讲解 Python 多线程的使用,包括线程创建、启动、停止、同步等方面。

线程创建

Python 中创建线程有两种方式:函数和类。我们先看函数方式的创建。

函数方式

在 Python 中,可以使用 threading 模块的 Thread() 方法来创建线程。Thread() 接受一个函数和一个参数,这个函数就是线程执行的代码,参数是传递给这个函数的参数,具体示例代码如下:

import threading

def say_hi(name):
    print(f"Hi, {name}!")

thread = threading.Thread(target=say_hi, args=('San Zhang',))
thread.start()

在上面的代码中,我们创建了一个 say_hi() 函数,用于输出“Hi, XXX!” 的字符串。然后创建了一个 Thread 对象,由 say_hi() 函数作为线程执行的代码,args=('San Zhang',) 表示将 'San Zhang' 这个参数传递给 say_hi() 函数。最后启动线程,我们可以看到输出了 Hi, San Zhang! 的字符串。

类方式

在 Python 中,可以创建一个类,并继承 threading.Thread 类来创建线程。这个类需要覆写 run() 方法,run() 方法中就是线程执行的代码。具体示例代码如下:

import threading

class PrintingThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):
        for i in range(3):
            print(f"{self.name}: {i}")

thread1 = PrintingThread('Thread 1')
thread2 = PrintingThread('Thread 2')
thread1.start()
thread2.start()

在上面的代码中,我们创建了一个 PrintingThread 类,并继承 threading.Thread 类。__init__() 方法中,我们通过 super() 调用父类的构造方法,将 name 作为参数传递给父类。然后,我们覆写了 run() 方法,用于打印 "name: i" 的字符串,其中 name 就是在 __init__() 方法中传递的参数。

然后,我们创建了两个 PrintingThread 对象,分别为 thread1thread2。最后,我们启动了这两个线程,我们可以看到输出了交替执行的 thread1thread2 的输出结果。

线程同步

在多线程编程中,线程同步是很重要的一部分,如果多个线程同时访问某个共享资源,那么很可能会导致数据错误或者线程间死锁等问题。Python 中可以使用一些机制来保证线程同步,比如互斥锁、条件变量等。

互斥锁

在 Python 中,可以创建一个 Lock() 对象来实现线程同步。具体示例代码如下:

import threading

counter = 0
lock = threading.Lock()

class CounterThread(threading.Thread):
    def run(self):
        global counter, lock
        for i in range(100000):
            lock.acquire()
            counter += 1
            lock.release()

thread1 = CounterThread()
thread2 = CounterThread()
thread1.start()
thread2.start()
thread1.join()
thread2.join()

print(counter)

在上面的代码中,我们创建了一个 Lock() 对象,称为 lock。然后我们创建了一个 CounterThread 类,并覆写了 run() 方法。run() 方法中,我们在访问 counter 变量之前先获得锁(使用 acquire() 方法),并在修改完 counter 变量后释放锁(使用 release() 方法)。这样就保证了对 counter 变量的访问是互斥的。最后,我们创建了两个 CounterThread 对象,启动这两个线程,并等待线程执行完毕。最后,输出 counter 变量的值。

条件变量

在 Python 中,可以创建一个 Condition() 对象来实现线程同步。具体示例代码如下:

import threading

queue = []
cond = threading.Condition()

class ProducerThread(threading.Thread):
    def run(self):
        global queue, cond
        for i in range(10):
            cond.acquire()
            queue.append(i)
            print(f"Produced {i}")
            cond.notify()
            cond.release()

class ConsumerThread(threading.Thread):
    def run(self):
        global queue, cond
        for i in range(10):
            cond.acquire()
            while not queue:
                cond.wait()
            item = queue.pop(0)
            print(f"Consumed {item}")
            cond.release()

producer = ProducerThread()
consumer = ConsumerThread()
producer.start()
consumer.start()
producer.join()
consumer.join()

在上面的代码中,我们创建了一个 Condition() 对象,称为 cond。然后我们创建了一个 ProducerThread 类,并覆写了 run() 方法。run() 方法中,我们向 queue 列表中添加元素,并输出 "Produced i" 的字符串。然后调用 cond.notify() 方法唤醒等待在 cond 条件变量上的线程,并最后释放锁(使用 release() 方法)。

我们还创建了一个 ConsumerThread 类,并覆写了 run() 方法。run() 方法中,我们先获取锁(使用 acquire() 方法),然后判断 queue 是否为空。如果为空,就调用 cond.wait() 方法等待唤醒。如果不为空,就从 queue 列表中弹出第一个元素,输出 "Consumed i" 的字符串,并释放锁(使用 release() 方法)。

最后,我们创建了一个 ProducerThread 和一个 ConsumerThread 对象,启动这两个线程,并等待线程执行完毕。

线程停止

线程的停止可以使用 threading.Event() 来控制。 Event 是一个线程同步工具,一个线程调用 Event.wait() 方法会进入阻塞状态,直到另一个线程调用 Event.set() 方法为止。

具体示例代码如下:

import threading

stop_event = threading.Event()

class StoppableThread(threading.Thread):
    def run(self):
        global stop_event
        i = 0
        while not stop_event.is_set():
            i += 1
            print(i)
        print("Stopped")

thread1 = StoppableThread()
thread2 = StoppableThread()
thread1.start()
thread2.start()

# 通过 Event 控制线程停止
stop_event.set()

thread1.join()
thread2.join()

在上面的代码中,我们创建了一个 Event() 对象,称为 stop_event。然后我们创建了一个 StoppableThread 类,并覆写了 run() 方法。run() 方法中,我们使用了一个循环来输出数字,当 stop_eventis_set() 方法返回 True 的时候,就退出循环,并输出 "Stopped" 的字符串。最后,我们创建了两个 StoppableThread 对象,启动这两个线程,并等待一段时间后,通过 stop_event.set() 方法控制线程停止。

总结

本文详细讲解了 Python 多线程的使用方法,包括线程创建、启动、停止、同步等方面的内容。通过阅读本文,读者可以清楚地了解 Python 多线程编程的基础知识,并能够在实践中灵活运用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python多线程使用方法详细讲解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Python实现图片转字符画的代码实例

    当你想将一张图片转换成由字符构成的艺术品时,可以使用Python编程语言来实现这个过程。这个过程包括了读取图像、将图像转换成灰度图、将灰度值映射到字符集合中,最后将结果打印出来或保存到文件中。 下面是这个过程的详细攻略: 步骤一:安装需要的库 在Python中,有很多第三方库可以用来读取和处理图像。这里我们使用 Python Imaging Library …

    python 2023年6月2日
    00
  • Python之用户输入的实例

    下面是Python用户输入的完整攻略。 标题:Python之用户输入的实例 1、用户输入基本操作 Python中的input()函数可以接收用户输入的数据。当程序运行到该语句时,程序会暂停并等待用户输入。当用户输入完成后,该函数会把接收到的数据以字符串的形式返回给调用的程序。 示例1: #用户输入自己的姓名和年龄 name = input("请输入…

    python 2023年6月5日
    00
  • Python操作Excel的学习笔记

    下面我来详细讲解一下“Python操作Excel的学习笔记”的完整实例教程。 Python操作Excel的学习笔记 介绍 本教程将介绍如何使用Python来操作Excel文件。我们将使用xlrd、xlwt和openpyxl这三个库来读取、写入和编辑Excel文件。 安装 在开始操作Excel之前,我们需要安装xlrd、xlwt和openpyxl这三个库。在安…

    python 2023年5月13日
    00
  • CentOS 程序设计语言python版本太低如何手动升级

    下面我将为你详细解释如何手动升级 CentOS 系统中的 Python 版本。 1. 安装编译工具和依赖包 首先,在进行 Python 版本升级前,需要确保已经安装了编译工具和依赖包。可以通过以下命令安装: sudo yum groupinstall "Development tools" -y sudo yum install zlib…

    python 2023年5月30日
    00
  • 详解Python 中的 defaultdict 数据类型

    详解Python中的defaultdict数据类型 在Python的集合模块collections中,提供了一个常用的数据类型defaultdict,它是一种有着默认值的字典类型,在字典中如果对于一个不存在的键,默认值会被Python自动赋上,从而避免了KeyError异常的产生。 定义一个defaultdict 使用defaultdict首先需要导入col…

    python 2023年6月3日
    00
  • python线程池如何使用

    让我来为您介绍如何使用 Python 线程池。 什么是线程池 线程池是一种预先分配了一组线程的技术,可用于执行许多异步操作,从而不必每次都创建新的线程,这节省了时间和资源。 Python中的线程池 Python标准库中提供了 concurrent.futures 模块,该模块有两个类:ThreadPoolExecutor 和 ProcessPoolExecu…

    python 2023年6月6日
    00
  • Python+pyecharts绘制交互式可视化图表

    下面是我对“Python+pyecharts绘制交互式可视化图表”的完整攻略。 一、什么是pyecharts pyecharts是一款基于Echarts 3.x和Python编写的图表库。它能够快速简单地绘制出各种交互式可视化图表,支持30+种图表类型,包括但不限于折线图、柱状图、散点图、地图等,还可以进行多种配置和样式的自定义。 二、pyecharts的安…

    python 2023年6月6日
    00
  • Python中bytes和str的区别与联系详解

    Python中bytes和str的区别与联系详解 在Python中,bytes和str是两种常用的数据类型,它们看似很相似,但实际上存在着很大的差异。本文将详细讲解bytes和str的区别与联系,并且提供示例说明。 bytes与str的区别 1. 数据类型 bytes是Python中的一种二进制数据类型,表示字节序列,是不可变的序列。而str是表示Unico…

    python 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部