Python线程threading模块用法详解

Python线程threading模块用法详解

Python线程是为了实现多任务而提出来的一种技术。在Python中,线程是通过threading模块来实现的。本文将详细介绍threading模块的用法,包括线程的创建、启动、停止等所有相关知识。

线程的创建

在使用threading模块创建线程时,可以有两种方式:

1. 通过继承Thread

import threading

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

    def run(self):
        print("Thread " + self.name + " running")

t1 = MyThread("t1")
t1.start()

2. 通过实例化Thread

import threading

def thread_func(name):
    print("Thread " + name + " running")

t2 = threading.Thread(target=thread_func, args=("t2",))
t2.start()

在以上例子中,我们分别展示了两种方式。

第一种方式是继承Thread类,并在类中实现run()方法,在run()方法中编写线程的执行任务。

第二种方式是通过定义一个线程函数,并将其作为Thread类构造函数的参数传递,同时需要将该函数程序逻辑定义在args参数中,如上代码中的thread_func函数。

线程的启动与停止

启动线程只需调用Thread对象的start()方法即可。

import threading

def thread_func(name):
    print("Thread " + name + " running")

t = threading.Thread(target=thread_func, args=("t",))
t.start()

停止线程有两种方式:

1. 通过_stop()方法

_stop()方法是Thread类中自带的方法,可以用来停止线程。但需要注意的是,此方法不推荐使用,因为可能会在程序中短时间内留下一些脏数据。

import threading
import time

def thread_func():
    print("Thread running")
    time.sleep(3)

t = threading.Thread(target=thread_func)
t.start()
t._stop()

2. 通过标志位停止线程

可以通过设置一个标志位,来通知线程该停止了。在线程中需要做的事情是,在执行任务的过程中,判断标志位的值是否为True,如果为False,则终止线程。

import threading
import time

flag = True

def thread_func():
    print("Thread running")
    while flag:
        time.sleep(0.1)
    print("Thread stopped")

t = threading.Thread(target=thread_func)
t.start()

time.sleep(1)
flag = False

在以上例子中,我们定义了一个flag变量,作为停止线程的标志位,并在thread_func函数中使用该标志位进行判断。在主程序中,睡眠1秒后,将该标志位设置为False即可停止线程。

示例1:线程同步

当多个线程同时访问一个共享资源时,可能会出现数据混乱,因此我们需要通过线程同步的方式来解决这个问题。

以下是一个简单的线程同步的例子:

import threading
import time

class Counter(object):
    def __init__(self, count):
        self.count = count
        self.lock = threading.Lock()

    def add(self, n):
        self.lock.acquire()
        self.count += n
        time.sleep(1)
        print("add %d, the count now is %d" % (n, self.count))
        self.lock.release()

    def reduce(self, n):
        self.lock.acquire()
        self.count -= n
        time.sleep(1)
        print("reduce %d, the count now is %d" % (n, self.count))
        self.lock.release()

def add(c):
    for i in range(5):
        c.add(1)

def reduce(c):
    for i in range(5):
        c.reduce(1)

counter = Counter(10)

t1 = threading.Thread(target=add, args=(counter,))
t2 = threading.Thread(target=reduce, args=(counter,))

t1.start()
t2.start()

t1.join()
t2.join()

在以上例子中,我们定义了一个Counter类,其中包含addreduce两个方法,分别用于加和减。在类的成员变量中,我们使用了Lock类,用于线程同步。在addreduce方法中,使用了lock对象对部分程序逻辑进行了阻塞,以保证线程同步。

示例2:线程池

线程池是一种可以重用线程的技术,它可以更好地控制线程的数量和生命周期。以下是一个简单的线程池的例子:

import threading
import time

class ThreadPool(object):
    def __init__(self, max_threads):
        self.queue = []
        self.lock = threading.Lock()
        self.pool = [threading.Thread(target=self.run) for i in range(max_threads)]
        self.running = True
        self.thread_limit = max_threads
        for t in self.pool:
            t.start()

    def add_task(self, task):
        self.lock.acquire()
        self.queue.insert(0, task)
        self.lock.release()

    def run(self):
        while self.running:
            self.lock.acquire()
            if len(self.queue):
                task = self.queue.pop()
                self.lock.release()
                task()
            else:
                self.lock.release()

            time.sleep(0.1)

    def stop(self):
        self.running = False
        for t in self.pool:
            t.join()

def func_a():
    print("func_a running")
    time.sleep(1)

def func_b():
    print("func_b running")
    time.sleep(1)

pool = ThreadPool(3)
pool.add_task(func_a)
pool.add_task(func_b)

pool.stop()

在以上例子中,我们定义了一个ThreadPool类,使用了一个队列来存储线程任务。在类的构造函数中创建了一定数量的线程,在队列中存储多个任务。在run方法中,使用了while循环,不断取出队列中的任务,并执行。在stop方法中,通过设置running标志位为False,停止线程池中所有线程。

最后,我们在实际应用中,可以根据自己的需求,灵活运用threading模块中不同的方法和技巧,来实现对线程的有效管理和控制。

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

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

相关文章

  • 13个最常用的Python深度学习库介绍

    13个最常用的Python深度学习库介绍 本文将介绍13个最常用的Python深度学习库,包括TensorFlow、PyTorch、Keras、CNTK、Theano、MXNet、Caffe、Chainer、Lasagne、PaddlePaddle、Gluon、Torch和DeepLearning4J。我们将介绍每个库的基本原理、特点和使用方法,并提供两个示…

    python 2023年5月14日
    00
  • Python3实现的字典、列表和json对象互转功能示例

    Python3实现字典、列表和JSON对象互转功能示例 1.背景 在Python编程中,字典、列表和JSON对象是常用的数据结构。这些数据结构在不同的场景下都有不同的用途,而且在实际应用中也需要进行互相转换。因此,学会如何在它们之间进行转换是非常重要的,也是我们必须掌握的基本操作。 2.实现方法 将一个字典或列表对象转换为JSON对象可以通过Python中的…

    python 2023年5月13日
    00
  • Python对Excel按列值筛选并拆分表格到多个文件的代码

    我来详细讲解一下Python对Excel按列值筛选并拆分表格到多个文件的代码的完整实例教程。 示例说明 在本教程中,我们将以一个实例来说明如何使用Python对Excel表格按列值进行筛选并拆分成多个文件。假设我们有一张Excel表格,其中包含了两列数据:日期和销售额。现在我们需要按照日期来筛选表格,并将符合条件的行拆分成多个Excel文件。 我们的示例Ex…

    python 2023年5月13日
    00
  • python函数默认参数使用避坑指南

    Python 函数默认参数使用避坑指南 在 Python 中,函数的默认参数是一种非常方便的语法,它可用于简化函数的调用方式。在使用默认参数时,我们需要注意一些问题,否则会因为一些陷阱而导致程序出错或无法按照预期运行。本篇文章主要是为了避免使用默认参数时遇到的一些陷阱,给出帮助和指导。 1. 默认参数的使用方法 Python 中默认参数的使用方法非常简单,只…

    python 2023年6月5日
    00
  • 利用Python实现自动扫雷小脚本

    利用Python实现自动扫雷小脚本的攻略如下: 一、思路 使用Python获取窗口句柄,并将窗口切换到扫雷程序窗口,以便后续的操作; 获取扫雷程序的界面信息,包括雷区大小、雷数以及每个格子的位置、大小等信息; 利用图像处理技术识别雷区中每个格子的状态(是雷、数字还是空白),并执行相应的操作; 不断循环以上步骤,直到游戏结束。 二、操作步骤 安装必要的Pyth…

    python 2023年5月19日
    00
  • python 提取文件的小程序

    下面是详细讲解“Python 提取文件的小程序”的完整攻略。 1. 确定文件路径 首先需要确定要提取的文件在哪个地方。可以使用 Python 的 os 模块中的 getcwd() 函数获取当前工作目录,然后再通过 os.path.join() 拼接出完整的文件路径。 示例代码: import os file_name = "example.txt&…

    python 2023年5月18日
    00
  • Python cookbook(数据结构与算法)找出序列中出现次数最多的元素算法示例

    下面是针对“Python cookbook(数据结构与算法)找出序列中出现次数最多的元素算法示例”的攻略: 一、背景介绍 在进行数据分析、机器学习等领域的数据处理过程中,经常需要对某个序列中出现次数最多的元素进行筛选,比如电商平台需要知道每个月哪个商品的销量最高,或者社交媒体需要知道哪些话题被讨论得最多等。Python cookbook提供了一些高效的算法来…

    python 2023年6月3日
    00
  • Python爬取股票信息,并可视化数据的示例

    下面我将为您详细讲解“Python爬取股票信息,并可视化数据的示例”的完整攻略,步骤如下: 1. 确定目标网站并分析页面结构 首先,我们需要确定目标网站,并分析该网站的页面结构和获取数据的方式。在这里,我们选择使用新浪财经网站作为示例,目标链接为:https://finance.sina.com.cn/realstock/company/sh600519/n…

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