python创建线程和结束线程

这篇具有很好参考价值的文章主要介绍了python创建线程和结束线程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

👽发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。

python创建线程和结束线程

在 Python 中,线程是一种轻量级的执行单元,允许我们在程序中同时执行多个任务。线程的创建和结束是多线程编程中的核心概念之一。在本文中,我们将学习如何使用 Python 创建线程,并探讨如何优雅地结束线程。

创建线程

Python 中创建线程非常简单,可以使用 threading 模块来实现。下面是一个简单的例子:

import threading
import time

def print_numbers():
    for i in range(1, 6):
        print(i)
        time.sleep(1)

# 创建线程
thread = threading.Thread(target=print_numbers)

# 启动线程
thread.start()

# 主线程等待子线程执行完成
thread.join()

print("线程执行完成!")

在这个例子中,我们创建了一个名为 print_numbers 的函数,该函数用于打印 1 到 5 的数字。然后,我们使用 threading.Thread 类创建了一个新的线程,并指定了要执行的目标函数。最后,通过调用 start() 方法启动线程,通过 join() 方法等待线程执行完成。

结束线程

结束线程通常是为了让程序在不需要线程继续执行时能够正常退出,或者在特定条件下终止线程的执行。在 Python 中,线程是无法直接终止的,但是可以通过设置标志位或者发送信号的方式让线程自行退出。下面是一个简单的例子:

import threading
import time

# 全局标志位,控制线程执行
is_running = True

def count_numbers():
    i = 1
    while is_running:
        print(i)
        i += 1
        time.sleep(1)

# 创建线程
thread = threading.Thread(target=count_numbers)

# 启动线程
thread.start()

# 主线程等待一段时间后修改标志位,结束线程
time.sleep(5)
is_running = False

print("等待线程执行完成...")
thread.join()

print("线程执行完成!")

在这个例子中,我们创建了一个名为 count_numbers 的函数,该函数会不断地打印数字,并通过一个全局变量 is_running 控制线程的执行。在主线程中,我们等待了 5 秒后将 is_running 设置为 False,从而让线程自行退出。

安全结束线程

除了设置标志位的方式外,有时候我们可能需要更加安全和可靠地结束线程。Python 中的线程并没有提供直接的方法来强制终止线程,但可以使用一些技巧来安全地结束线程,比如使用 Thread 对象的 Event

下面是一个使用 Event 来结束线程的示例:

import threading
import time

# 创建 Event 对象
stop_event = threading.Event()

def count_numbers():
    i = 1
    while not stop_event.is_set():
        print(i)
        i += 1
        time.sleep(1)

# 创建线程
thread = threading.Thread(target=count_numbers)

# 启动线程
thread.start()

# 主线程等待一段时间后设置 Event,结束线程
time.sleep(5)
stop_event.set()

print("等待线程执行完成...")
thread.join()

print("线程执行完成!")

在这个例子中,我们创建了一个 Event 对象 stop_event,线程在每次循环中检查该事件是否被设置。在主线程中,我们等待了 5 秒后设置了 stop_event,从而结束了线程的执行。

异常处理

在线程中,异常的处理也是一个重要的问题。如果线程中发生了异常而没有处理,整个线程可能会意外终止。因此,在线程中要使用 try-except 语句来捕获异常,并进行适当的处理。

下面是一个简单的例子:

import threading
import time

def task():
    try:
        # 这里是线程执行的任务
        print("任务开始...")
        time.sleep(3)
        raise Exception("人为抛出异常")
    except Exception as e:
        print(f"捕获到异常:{e}")

# 创建线程
thread = threading.Thread(target=task)

# 启动线程
thread.start()

# 主线程等待线程执行完成
thread.join()

print("线程执行完成!")

在这个例子中,线程中的任务抛出了一个异常,但由于我们在 task 函数中使用了 try-except 语句,因此异常被捕获并打印出来,而线程并没有意外终止。

使用线程池管理线程

在实际开发中,如果需要频繁地创建和销毁线程,可能会导致性能下降。为了更有效地管理线程,可以使用线程池来重用线程对象。Python 提供了 concurrent.futures 模块,其中的 ThreadPoolExecutor 类可以帮助我们轻松地管理线程池。

下面是一个使用线程池的例子:

from concurrent.futures import ThreadPoolExecutor
import time

def task(n):
    print(f"任务 {n} 开始...")
    time.sleep(2)
    print(f"任务 {n} 完成!")

# 创建线程池
with ThreadPoolExecutor(max_workers=3) as executor:
    # 提交任务给线程池执行
    for i in range(1, 6):
        executor.submit(task, i)

print("所有任务执行完成!")

在这个例子中,我们使用 ThreadPoolExecutor 创建了一个最大工作线程数为 3 的线程池。然后,我们提交了 5 个任务给线程池执行。线程池会自动管理线程的创建和销毁,以及任务的调度。

使用 threading.Thread 的子类

除了直接使用 threading.Thread 类外,我们还可以通过继承 threading.Thread 创建自定义的线程类。这样做可以更好地组织代码,并且可以在子类中重写 run() 方法来定义线程执行的逻辑。

下面是一个简单的例子:

import threading
import time

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

    def run(self):
        print(f"{self.name} 线程开始执行...")
        time.sleep(3)
        print(f"{self.name} 线程执行完成!")

# 创建线程实例并启动
thread1 = MyThread("Thread 1")
thread2 = MyThread("Thread 2")

thread1.start()
thread2.start()

# 等待线程执行完成
thread1.join()
thread2.join()

print("所有线程执行完成!")

在这个例子中,我们定义了一个 MyThread 类,继承自 threading.Thread,并重写了 run() 方法来定义线程执行的逻辑。然后,我们创建了两个 MyThread 的实例,并启动了这两个线程。

线程同步与共享资源

在多线程编程中,经常会遇到多个线程同时访问共享资源的情况。为了避免竞争条件和数据不一致的问题,需要使用线程同步机制来保护共享资源。

使用锁(Lock)

锁是最常见的线程同步机制之一,Python 中的 threading.Lock 类可以用来创建锁对象。在访问共享资源之前,线程可以通过调用 acquire() 方法获取锁,访问完成后再调用 release() 方法释放锁。

下面是一个使用锁来保护共享资源的例子:

import threading

shared_resource = 0
lock = threading.Lock()

def update_shared_resource():
    global shared_resource
    for _ in range(100000):
        lock.acquire()
        shared_resource += 1
        lock.release()

# 创建多个线程来更新共享资源
threads = []
for _ in range(5):
    t = threading.Thread(target=update_shared_resource)
    threads.append(t)
    t.start()

# 等待所有线程执行完成
for t in threads:
    t.join()

print("共享资源的值为:", shared_resource)

在这个例子中,我们创建了一个名为 shared_resource 的共享变量,然后使用 threading.Lock 创建了一个锁对象 lock。在 update_shared_resource 函数中,我们使用锁来保护对 shared_resource 的访问,从而避免了多个线程同时修改共享资源的问题。

使用条件变量(Condition)

条件变量是另一种常见的线程同步机制,Python 中的 threading.Condition 类可以用来创建条件变量对象。条件变量通常与锁结合使用,可以在满足特定条件时通知等待的线程。

下面是一个使用条件变量来实现生产者-消费者模式的例子:

import threading
import time

MAX_ITEMS = 5
items = []
condition = threading.Condition()

def producer():
    for i in range(10):
        time.sleep(1)
        with condition:
            if len(items) >= MAX_ITEMS:
                print("仓库已满,生产者等待...")
                condition.wait()
            print("生产者生产一个商品")
            items.append(i)
            condition.notify()

def consumer():
    for i in range(10):
        time.sleep(1.5)
        with condition:
            while not items:
                print("仓库为空,消费者等待...")
                condition.wait()
            item = items.pop(0)
            print(f"消费者消费了商品 {item}")
            condition.notify()

# 创建生产者和消费者线程并启动
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

producer_thread.start()
consumer_thread.start()

# 等待线程执行完成
producer_thread.join()
consumer_thread.join()

print("所有商品已被生产和消费完毕!")

在这个例子中,我们使用了条件变量 condition 来实现生产者-消费者模式。生产者线程在仓库满时等待,消费者线程在仓库空时等待,并在生产或消费完成后通过 notify() 方法通知等待的线程。

使用队列实现线程间通信

除了使用锁和条件变量等同步机制外,还可以使用队列来实现线程间的安全通信。Python 中的 queue.Queue 类提供了线程安全的队列实现,可以在多个线程之间安全地传递数据。

下面是一个使用队列实现生产者-消费者模式的例子:

import threading
import queue
import time

MAX_ITEMS = 5
queue = queue.Queue(MAX_ITEMS)

def producer():
    for i in range(10):
        time.sleep(1)
        try:
            queue.put(i, block=True, timeout=1)
            print("生产者生产一个商品")
        except queue.Full:
            print("仓库已满,生产者等待...")

def consumer():
    for i in range(10):
        time.sleep(1.5)
        try:
            item = queue.get(block=True, timeout=1)
            print(f"消费者消费了商品 {item}")
        except queue.Empty:
            print("仓库为空,消费者等待...")

# 创建生产者和消费者线程并启动
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

producer_thread.start()
consumer_thread.start()

# 等待线程执行完成
producer_thread.join()
consumer_thread.join()

print("所有商品已被生产和消费完毕!")

在这个例子中,我们使用了 queue.Queue 类来实现生产者-消费者模式。生产者线程通过 put() 方法向队列中添加商品,消费者线程通过 get() 方法从队列中取出商品。当队列已满时,生产者线程会等待;当队列为空时,消费者线程会等待。

使用队列实现线程间通信的好处在于,它提供了一种简单而安全的方式来传递数据,避免了显式的锁和条件变量的使用。

定时结束线程

有时候,我们希望线程在一定时间内执行完毕或者超时退出。Python 中可以利用定时器来实现这一功能。定时器可以在指定的时间后触发一个事件,我们可以利用这个特性来控制线程的执行时间。

下面是一个使用定时器结束线程的例子:

import threading
import time

def task():
    print("线程开始执行...")
    time.sleep(3)  # 模拟线程执行时间
    print("线程执行完成!")

# 创建线程
thread = threading.Thread(target=task)

# 启动线程
thread.start()

# 定时器,3秒后设置线程结束标志
def set_thread_finished():
    print("定时器触发,设置线程结束标志...")
    thread.finished = True

timer = threading.Timer(3, set_thread_finished)
timer.start()

# 主线程等待线程执行完成
thread.join()

print("线程执行完成!")

在这个例子中,我们创建了一个定时器 timer,在 3 秒后触发 set_thread_finished 函数,该函数设置了线程的结束标志。线程在执行时会检查结束标志,如果标志被设置,则提前退出。这样就实现了在指定时间后结束线程的功能。

使用 threading.Event 实现线程等待

除了定时器,我们还可以使用 threading.Event 来实现线程的等待和超时退出。Event 是线程间通信的一种机制,可以用来设置信号、等待信号等操作。

下面是一个使用 Event 实现线程等待的例子:

import threading
import time

# 创建 Event 对象
event = threading.Event()

def task():
    print("线程开始执行...")
    event.wait(3)  # 等待事件触发,超时时间为3秒
    if event.is_set():
        print("事件被触发,线程执行完成!")
    else:
        print("超时退出,线程执行未完成!")

# 创建线程
thread = threading.Thread(target=task)

# 启动线程
thread.start()

# 等待一段时间后设置事件
time.sleep(2)
print("等待2秒后设置事件...")
event.set()

# 主线程等待线程执行完成
thread.join()

print("线程执行完成!")

在这个例子中,线程在执行时等待事件的触发,如果在3秒内事件被设置,则线程执行完成;否则,线程会在超时后退出。这样就实现了在指定时间内结束线程的功能。

总结

在本文中,我们探讨了在 Python 中创建线程、结束线程以及线程管理的多种方法。我们从创建线程的基础开始,介绍了使用 threading 模块创建线程的方法,并展示了如何优雅地结束线程。接着,我们深入讨论了线程同步与共享资源的问题,介绍了使用锁、条件变量和队列等机制来保护共享资源、实现线程间通信的方法。然后,我们探讨了如何使用定时器和事件来实现线程的定时结束和超时退出,从而更灵活地控制线程的执行时间。

总的来说,本文全面介绍了多线程编程中的关键概念和技术,并提供了丰富的代码示例来帮助读者更好地理解和应用这些技术。通过合理地使用线程管理和同步机制,我们可以编写出高效、可靠的多线程程序,更好地利用计算资源,提高程序的性能和可维护性。希望本文对读者在 Python 多线程编程方面有所帮助。

python创建线程和结束线程,Python领域开发技术应用技术,python,开发语言,线程,执行单元文章来源地址https://www.toymoban.com/news/detail-858042.html

到了这里,关于python创建线程和结束线程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Windows线程开发】Windows线程同步技术

    我们在上一章节中讲解了关于Windows的线程基础,相信大家已经对线程有了基本的概念。这一章节中,我们来讲讲线程同步技术,包括加锁技术(原子锁和互斥体)和事件,信号量。 原子锁主要解决的问题是多线程在操作符方面的问题。 相关问题: 多个线程对同一个数据进行

    2024年02月04日
    浏览(43)
  • pywebview桌面程序开发(技术路线:前端+Python,全网独一份!!!!!!)

    官网:https://pywebview.flowrl.com/ pywebview声称Build GUI for your Python program with JavaScript, HTML, and CSS。就是可以使用web技术来实现桌面应用程序开发。其内核我理解仍然是浏览器,只不过将浏览器封装成系统窗口,这样就可以将web无缝切换到桌面应用,相比pyQt等重武器还是比较方便的

    2024年03月14日
    浏览(42)
  • Python民宿农家乐攻略和点评系统毕业设计成品作品(4)开发技术文档

    开发操作系统:windows10 + 4G内存 + 500G硬盘 开发环境:Python3.8 开发语言:Python 开发框架:Django 开发工具:pycharm 数据库:mysql8 数据库管理工具:navicat 其他开发语言:html + css +javascript Python民宿农家乐攻略点评系统  后台管理文件 Python民宿农家乐攻略点评系统  前端文件 P

    2024年02月11日
    浏览(33)
  • 【河南省第二届技能大赛-物联网技术】C模块Python开发讲解

    这是基于样题进行讲解的文章,因为正式赛题尚未公布和样题类型相似。文章结尾提供了源码和环境链接,读者可以自行下载以进行更深入的学习和优化。 注意:题目中的API链接,是在比赛局域网环境下进行的,在平常练习的时候,用新大陆官方链接即可! 链接:新大陆官

    2024年02月01日
    浏览(52)
  • python运行selenium创建Edge浏览器更改默认下载路径的方法与防止程序结束后浏览器窗口自动关闭的方法

    结合chatgpt与csdn查阅资料后 得到解决方法: 其中 “D:Downloads_test”改为你自己想要默认下载路径, \\\"download.prompt_for_download\\\"为下载文件开始时Edge浏览器是否弹出另存为窗口,True则触发下载时会弹出另存为窗口,False则直接将文件下载到默认下载路径中。 另存为窗口长相如下

    2024年02月11日
    浏览(33)
  • 37.Python从入门到精通—Python3 多线程 线程模块 使用 threading 模块创建线程

    在Python 3中,线程模块已被重命名为_thread,同时还引入了更高级别的 threading 模块,它允许创建线程对象并提供了更多的方法来控制线程的行为。 以下是一个简单的示例,演示如何使用 threading 模块创建并启动线程: 在这个例子中,我们创建了一个名为 print_numbers 的函数,它

    2024年04月26日
    浏览(33)
  • python 创建和使用线程池

    众所周知,python3多线程有threading,很好的支持了多线程,那么问题来了,为什么还需要线程池呢,其实很好回答,如果你要爬取网站有八百页,每页设置一个线程,难道能开启八百个么,光切换的时间也很高了吧。这时候就需要用到线程池,可以设置一个20的线程池,同时只

    2024年02月15日
    浏览(29)
  • 微信开发之一键创建标签的技术实现

    简要描述: 添加标签 请求URL: http://域名地址/addContactLabel 请求方式: POST 请求头Headers: Content-Type:application/json Authorization:login接口返回 参数: 参数名 必选 类型 说明 wId 是 String 登录实例标识 labelName 是 String 标签名称 请求参数示例 成功返回示例 错误返回示例 返回数据

    2024年02月11日
    浏览(25)
  • 第一篇【传奇开心果系列】Python的游戏库pygame技术点案例示例:深度解读实战开发飞机大战经典游戏案例

    开发飞机大战游戏不仅能满足广大玩家的娱乐需求,提供寓教于乐的学习机会,也是技术实践、创新实验和商业探索的重要载体,具有多维度的社会与经济价值。 开发飞机大战游戏具有多方面的意义,涵盖娱乐、教育、技术实践与创新等多个层面: 娱乐价值 : 休闲娱乐 :

    2024年04月23日
    浏览(65)
  • 微信开发之一键创建微信群聊的技术实现

    本接口为敏感接口,请查阅调用规范手册 创建后,手机上不会显示该群,往该群主动发条消息手机即可显示。 请求URL: http://域名地址/createChatroom 请求方式: POST 请求头Headers: Content-Type:application/json Authorization:login接口返回 参数: 参数名 必选 类型 说明 wId 是 String 登录

    2024年02月11日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包