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

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 提供了内置函数 open() 和 close() 用于打开和关闭文件,以及提供了一些文件操作的方法。通过这些函数,我们可以直接打开一个文件,读取或修改其中的内容,最后保存并关闭文件。 打开文件 使用内置函数 open() 可以打开一个文件,函数语法…

    python 2023年6月5日
    00
  • 详解python之异步编程

    异步编程是一种高效的编程方式,可以提高程序的并发性和响应速度。Python提供了asyncio库,可以方便地实现异步编程。本文将详细讲解Python之异步编程的完整攻略,包括异步编程的概念、asyncio库的使用、协程的实现和示例代码。 异步编程的概念 异步编程是一种编程方式,可以在单线程中实现并发执行多个任务。异步编程的核心是协程,协程是一种轻量级的线程,…

    python 2023年5月15日
    00
  • Python3如何对urllib和urllib2进行重构

    Python3中,urllib和urllib2均被合并到了一个名为urllib的包中,并且在使用上也有了一些更改,这就导致了在一些Python2项目的升级过程中,需要对urllib和urllib2进行重构。下面是对Python3对urllib、urllib2重构的完整攻略: 1. 使用前import 在使用urllib前需要import,import方式如下…

    python 2023年6月3日
    00
  • 如何使用 Python 从已知私钥生成以太坊公钥

    【问题标题】:How do I generate an Ethereum public key from a known private key using Python如何使用 Python 从已知私钥生成以太坊公钥 【发布时间】:2023-04-07 02:23:01 【问题描述】: 我有兴趣使用 Python 从私钥生成以太坊公钥。我试过谷歌搜索并找到…

    Python开发 2023年4月7日
    00
  • python正则表达式re.search()的基本使用教程

    当谈到处理字符串时,正则表达式是一个必备的工具。使用Python内置的正则表达式模块re可以让我们更加容易地操作字符串。re.search()是re模块中最著名的函数之一,它可以在字符串中查找满足正则表达式的第一个匹配项。以下是使用re.search()函数的基本教程。 步骤 导入re模块 python import re 创建一个正则表达式对象 pytho…

    python 2023年5月13日
    00
  • python 中不同包 类 方法 之间的调用详解

    下面我将来一步步详细讲解“python 中不同包 类 方法 之间的调用”的攻略。 1. 包的导入 要使用不同包之间的类或方法,首先需要导入相应的包。在Python中,可以使用import命令来导入包。一个包就是一个由模块和其它子包组成的文件夹。 1.1. 导入同级目录下的包 当要导入同级目录下的包时,可以使用以下语句: import 包名 例如,有一个名为t…

    python 2023年6月3日
    00
  • 如何在启动时在 Python IDLE 中预加载 Python 模块?

    【问题标题】:How to Pre-load Python Modules in Python IDLE on Startup?如何在启动时在 Python IDLE 中预加载 Python 模块? 【发布时间】:2023-04-01 03:58:01 【问题描述】: 我在 Windows 7 上。当我启动 Python IDLE 时,我希望它预加载:pan…

    Python开发 2023年4月8日
    00
  • 使用Numpy和Matplotlib绘制正态分布图

    好的。首先,我们需要简单介绍一下Numpy和Matplotlib这两个库。 Numpy NumPy(Numerical Python)是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,同时也针对数组运算提供大量的数学函数库。这是 Python 语言的开源软件之一,也是数据分析、数据处理和科学计算等领域最常用的库之一。 Matplotlib…

    python-answer 2023年3月25日
    00
合作推广
合作推广
分享本页
返回顶部