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日

相关文章

  • 在Python中使用NumPy创建一个白色图像

    以下是在Python中使用NumPy创建一个白色图像的完整攻略: 1. 导入NumPy库 在开始之前,我们需要导入NumPy库以便于使用其功能: import numpy as np 2. 创建一个全部为白色的图像 接下来,我们可以使用NumPy的ndarray数组类型创建一个全部为白色的图像。具体来说,我们可以使用numpy.ones函数在创建数组时将所有…

    python-answer 2023年3月25日
    00
  • python 3.7.0 下pillow安装方法

    下面是Python 3.7.0下安装Pillow的完整攻略: 安装前准备 在开始安装过程前,需要先确认一下以下几点: 电脑中已经安装好了Python 3.7.0版本,可以通过命令行输入python –version或python3 –version来确认版本号。 已经安装pip,可以通过输入pip –version来检测pip是否已经正确安装。 确认了…

    python 2023年5月14日
    00
  • 十个Python程序员易犯的错误

    下面是对“十个Python程序员易犯的错误”进行详细讲解的攻略。 错误1:没有理解Python的作用域 在Python中,作用域是由代码块中的缩进决定的。如果在函数内部定义一个变量,并在函数外尝试访问该变量,将会遇到NameError的错误。 示例: def my_func(): my_var = 10 print(my_var) 输出: NameError…

    python 2023年5月13日
    00
  • 如何将一维图元数组转换为二维Numpy数组

    将一维图元数组转换为二维Numpy数组的过程可以用Numpy模块中的reshape()函数实现。 下面的代码展示了如何将一维图元数组转换为二维Numpy数组。假设我们有一个一维图元数组,其中包含10个数据项: import numpy as np one_dim_array = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]…

    python-answer 2023年3月25日
    00
  • Python3+PyCharm+Django+Django REST framework配置与简单开发教程

    Python3+PyCharm+Django+DjangoRESTframework配置与简单开发教程 本文将详细讲解如何使用Python3、PyCharm、Django和DjangoRESTframework进行Web开发。我们将从环境配置开始,一步步地介绍如何创建Django项目和DjangoRESTframework应用,并编写简单的API接口。 环境…

    python 2023年5月15日
    00
  • Python自动化办公之编写PDF拆分工具

    下面是关于“Python自动化办公之编写PDF拆分工具”的完整攻略。 1. 概述 本攻略将通过Python语言编写一个自动批量拆分PDF文件的工具,方便用户快速地进行PDF文件拆分操作。 2. 准备工作 在开始编写代码之前,我们需要先安装Python的相关包,主要包括PyPDF2、os、argparse等模块。这些可以通过pip进行安装,命令如下: pip …

    python 2023年6月5日
    00
  • python根据出生日期返回年龄的方法

    下面是关于“python根据出生日期返回年龄的方法”的完整攻略。首先需要明确一个概念,就是将当前日期减去出生日期,并按年份计算其差值,即为年龄。 1. 获取当前日期与出生日期 使用Python自带的datetime模块可以轻松获取当前日期,例如: from datetime import date today = date.today() 要获取出生日期,可…

    python 2023年6月2日
    00
  • 在Python中的Django框架中进行字符串翻译

    在Python中的Django框架中进行字符串翻译可以帮助我们更好地进行多语言支持,而Django中的翻译功能依赖于gettext库,下面是详细的操作步骤: 准备工作 在Django项目的settings.py中添加以下代码来配置语言和翻译文件的位置: LANGUAGE_CODE = ‘zh-hans’ TIME_ZONE = ‘Asia/Shanghai’…

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