【python实操】马上毕业了,你还不懂什么是守护线程、线程、进程?(附12306抢票程序-源代码)

news/2024/5/18 15:59:49/文章来源:https://blog.csdn.net/weixin_43796670/article/details/129793807
  • 作者:20岁爱吃必胜客(坤制作人),近十年开发经验, 跨域学习者,目前于海外某世界知名高校就读计算机相关专业。
  • 荣誉:阿里云博客专家认证、腾讯开发者社区优质创作者,在CTF省赛校赛多次取得好成绩。
  • 跨领域学习,喜欢摄影、弹吉他、咏春拳。文章深入浅出、语言风趣;爱吃必胜客社区创立者,旨在“发现美 欣赏美

  • 🏆 学习系列专栏
    。🏅 Python学习宝库
    。🏅 网络安全学习宝库

在这里插入图片描述

在这里插入图片描述

文章目录

  • ⭐️前言
    • 🌟 进程-process
    • 🌟 线程-Treading
    • 🌟 守护线程-Deamon Treading
      • ☀️java中的应用
      • ☀️python中的应用
  • ⭐️多线程模块threading
    • 🌟 使用锁来保护共享资源的访问
  • ⭐️queue模块
  • ⭐️多线程购买火车票的代码
  • ⭐️12306抢票程序-源代码

⭐️前言

下面我们先回顾基础知识,分别是:

在这里插入图片描述

进程-process
线程-Treading
守护线程-Deamon Treading

🌟 进程-process

进程就是一个装线程的容器
是线程的容器

进程就是一个个正在运行的独立软件

🌟 线程-Treading

又叫Light Weight Process LWP
轻量级进程
程序执行流的最小单元

线程组成:

线程id-----当前指令指针------寄存器集合---------堆栈

🌟 守护线程-Deamon Treading

☀️java中的应用

守护线程(Daemon Thread)是一种特殊的线程,其生命周期与 Java 虚拟机(JVM)的生命周期相同。当 JVM 中已不存在任何非守护线程时,虚拟机会自动退出,守护线程也会随之结束。因此,守护线程也被称为“服务线程”或“后台线程”

守护线程主要用于执行一些低优先级的任务,比如垃圾回收、内存管理、日志维护等工作。它通常不干扰其他线程的执行,当所有非守护线程执行结束后,它会被自动中断。

在 Java 中创建守护线程的方法是通过 Thread 类的 setDaemon() 方法,将线程设置为守护线程。当线程启动后,也可以使用 isDaemon() 方法来检查该线程是否为守护线程

需要注意的是,守护线程和非守护线程的区别在于它们的执行权限守护线程不能访问程序中的非守护线程或共享资源。因此,在使用守护线程时需要仔细考虑线程之间的依赖关系和共享资源的使用。

☀️python中的应用

Python中也有守护线程的概念,它与Java中的作用是相似的。在Python中,可以通过Thread类中的setDaemon方法来将线程设置为守护线程

在Python中,守护线程通常用于执行一些低优先级的任务或后台服务,例如监控另一个线程是否终止、自动保存数据等。当所有非守护线程结束时,守护线程也会自动结束,不会阻塞主进程的结束,这在一些长时间运行的程序中非常有用

需要注意的是,守护线程并不是万能的解决方案,它不能处理复杂的计算任务和涉及共享资源的并发问题。此外,在使用守护线程时需要仔细考虑线程之间的依赖关系和共享资源的使用,以避免数据竞争和死锁等问题。

下面是一个简单的例子,展示了如何在Python中创建守护线程:

import threading
import timedef print_time():for i in range(5):print("Current time:", time.ctime())time.sleep(1)t = threading.Thread(target=print_time)
t.daemon = True # 将线程设置为守护线程
t.start()print("Main process end.")

在上面的代码中,创建了一个名为print_time的函数,通过time模块打印当前时间,并在每次打印后等待1秒。然后创建了一个线程对象t,将print_time函数作为其目标函数,然后将线程设置为守护线程并启动。最后主进程打印一条结束信息。

⭐️多线程模块threading

在这里插入图片描述

现在用threading取代了thread模块。
Python中的threading模块提供了一种方便的方式来创建和管理线程。下面是使用threading模块创建和管理线程的示例代码:

import threading# 定义一个线程执行的任务函数
def task():print("This is a task function.")# 创建一个新线程
t = threading.Thread(target=task)# 启动该线程
t.start()# 等待该线程结束
t.join()print("Main thread ends.")

在上面的代码中,首先定义了一个task()函数,用于表示线程执行的具体任务。然后通过threading.Thread()创建一个新的线程对象t,并将task函数作为其目标函数。最后启动该线程并等待其运行结束,然后主线程继续执行。

除了这个基本的线程创建和启动方式,threading模块还提供了一些方便的功能,例如:

  • threading.current_thread():返回当前线程对象;
  • threading.active_count():返回当前活跃的线程数;
  • threading.enumerate():返回当前所有活跃线程的列表;
  • threading.Lock():创建一个锁对象,用于保护共享资源的互斥操作;
  • threading.Event():创建一个事件对象,用于线程之间的通信和同步等。

🌟 使用锁来保护共享资源的访问

在这里插入图片描述

在这里插入图片描述

下面是一个例子,演示如何使用锁来保护共享资源的访问

import threading# 定义一个共享变量
num = 0# 创建一个锁对象
lock = threading.Lock()# 定义一个线程执行的任务函数
def task():global numfor i in range(1000000):lock.acquire()num += 1lock.release()# 创建多个线程
threads = [threading.Thread(target=task) for i in range(10)]# 启动这些线程
for t in threads:t.start()# 等待这些线程结束
for t in threads:t.join()print("Final result:", num)

在上面的代码中,首先定义了一个共享变量num,它的值将被多个线程共同更新。然后创建一个锁对象lock,用于保护num变量的访问。接下来定义一个task()函数。

⭐️queue模块

实现多生产者,多消费者队列
该技术是多线程安全共享数据的最佳选择技术之一。

⭐️多线程购买火车票的代码

以下是一个多线程购买火车票的代码示例:

import threading
import timeclass Ticket:def __init__(self, name, quantity):self.name = nameself.quantity = quantityself.lock = threading.Lock()def buy(self, num):self.lock.acquire()try:if self.quantity >= num:self.quantity -= numprint(f"当前剩余车票:{self.quantity}")return Trueelse:print("余票不足,购票失败")return Falsefinally:self.lock.release()def worker(name, ticket, num):while True:if ticket.buy(num):print(f"{name} 购买 {num} 张车票成功!")breakelse:print(f"{name} 正在尝试购买车票中...")time.sleep(1)if __name__ == '__main__':t = Ticket("北京-上海", 10)threads = []for i in range(5):name = f"用户{i+1}"num = 2t1 = threading.Thread(target=worker, args=(name, t, num))threads.append(t1)for t in threads:t.start()for t in threads:t.join()

代码说明:

  1. Ticket 类表示火车票,包括票务名称和余票数量,以及一个锁对象用于线程同步。
  2. buy 方法用于购买车票,传入要购买的数量,如果余票足够则减少对应数量的余票,并返回 True,否则返回 False。
  3. worker 函数表示一个购票线程,不断尝试购买车票,如果成功则输出购买成功的信息,退出循环;否则等待 1 秒后重试。
  4. 在程序运行时创建 5 个购票线程,每个线程购买 2 张车票。线程启动后并发执行购票任务,直到所有线程购买成功为止。

注意:在实际开发中,购买车票需要连接网络、进行 IO 操作,并且可能会遇到一些异常情况,因此需要添加异常处理等相关代码来保证程序的稳定性和健壮性。

⭐️12306抢票程序-源代码

抢火车票需要模拟登陆、查询余票、提交订单等步骤,比较复杂,建议使用官方提供的API。以下是一个简单的模拟查询余票的Python代码示例。

import urllib.request
import json
import time# 设置参数
fromStation = '北京'
toStation = '上海'
departureDate = '2022-01-01'# 利用API查询余票
url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(departureDate, fromStation, toStation)
request = urllib.request.Request(url)
# 添加请求头
request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3')
response = urllib.request.urlopen(request)
result = response.read().decode('utf-8')
data = json.loads(result)# 解析结果
trains = data['data']['result']
for train in trains:trainList = train.split('|')if trainList[0] == '':  # 过滤无效车次continueif trainList[29] == 'Y':  # 判断是否有余票print('车次:{},余票数量:{}'.format(trainList[3], trainList[29]))# 设置查询间隔
time.sleep(10)

需要注意的是,12306官方接口的调用频率有限制,需要合理控制查询间隔,防止被封IP。此外,需要获取验证码和自动提交订单等功能可以使用第三方库,比如PyAutoGUI。但是使用自动化脚本抢票有一定风险,建议谨慎操作。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_276995.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

预训练语言模型(GPT,BERT)

文章目录GPT 模型预训练语言模型模型和学习BERT 模型去噪自编码器模型和学习模型特点References在自然语言处理中事先使用大规模语料学习基于 Transformer 等的语言模型,之后用于各种任务的学习和预测,称这种模型为预训练语言模型。代表性的模型有 BERT …

LCX端口转发之远程桌面端口双重映射多主机转发

1.下载LCX端口转发工具源码及程序: git clone https://github.com/UndefinedIdentifier/LCX lcx1 2.复制到目标机: winxp win2003 win7

上海亚商投顾:创业板指低开高走ChatGPT概念股再爆发

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。市场情绪大小指数今日走势分化,沪指盘中一度跌超1%,午后震荡回升跌幅收窄,创业板指则低开…

iOS多线程——GCD学习总结

文章目录多线程编程进程线程线程与进程的关系CPU核GCD简介为什么我们要使用GCD任务同步执行(sync):异步执行(async):队列(Dispatch Queue)串行队列(Serial Dispatch Queu…

Tensor高阶用法:快速掌握Tensor切分、变形等方法

要想在实际的应用中更灵活地用好 Tensor,Tensor 的连接、切分等操作也是必不可少的。我们就通过一些例子和图片来一块学习下。虽然这几个操作比较有难度,但只要耐心分析,然后上手练习,还是可以拿下的。 Tensor 的连接操作 在项目…

SQL语法基础

简介 SQL (Structured Query Language) 是具有数据操纵和数据定义等多种功能的数据库语言,这种语言具有交互性特点,能为用户提供极大的便利,数据库管理系统应充分利用SQL语言提高计算机应用系统的工作质量与效率。 以下介绍postgresql语法&am…

ChatGPT的多种用法(持续更新中。。。)

指南 写小说 “写一本拥有出人意料结局的推理小说。” “写一个让读者参与其中的交互小说。” “为孩子们写一本激励他们勇敢面对挑战的小说。” “编写一个有关科技创新的未来世界的小说。” “创造一个让读者感到沉浸其中的幻想故事。” 充当 Linux 终端 我想让你充当…

数据结构绪论

​ 文章目录1 知识结构2 数据结构的基本概念2.1 算法的基本概念2.2 数据结构三要素2.2.1 数据的逻辑结构线性结构非线性结构2.2.2 数据的存储(物理)结构数据结构的四种存储结构2.2.3 数据的运算3 算法的基本概念3.1 基本概念3.1.1 算法(Algor…

MIPI D-PHYv2.5笔记(5) -- 不同的PHY配置方式

声明:作者是做嵌入式软件开发的,并非专业的硬件设计人员,笔记内容根据自己的经验和对协议的理解输出,肯定存在有些理解和翻译不到位的地方,有疑问请参考原始规范看 规范5.7章节列举了一些常见的PHY配置,但实…

jsp+ssm在线考试系统+错题集Spring+SpringMVC+Mybatis编写实现的项目

本系统设计了三种角色:管理员,用户和教师。通过此系统,教师可以在线课程信息、考试内容、在线考试、考试管理进行发布。以及在线对试卷进行批阅和批量删除,用户可以对自己任课老师布置的课程信息进行下载,对老师已经批…

TryHackMe-Willow(boot2root)

Willow 柳树下有什么? 端口扫描 循例 nmap NFS枚举 直接挂载进来 存在一个rsa_key 暂时不知道有啥用,先去看80 Web枚举 进入80 看起来像是16进制,使用xxd转换 得到了用户名和rsa密文 在线计算器解密一下得到ssh的私钥 需要密码 ssh2johnj…

现在转行IT还有机会吗?

其实大部分所谓的机会都是建立在我们准备好的基础上的,因为大多数的企业并不会启用一个零基础毫无经验,或者没有企业所需要特质的人员。作为普通人而言,只有当你准备好之后,你才会看到机会,在这之前,你只会…

Web自动化测试入门

1.Web自动化测试的价值(为什么要做web自动化测试) 我们可以使用脚本语言代替人来进行测试 2.Web自动化测试相关技术: Selenium:支持多语言,行业内最火最主流Pytest/JUnit5:最好用最全面的单元测试框架Allure:测试报告3.Web自动化…

NotionAI - 文档领域的ChatGPT,一款 AI 加持的在线文档编辑和管理工具

简介 NotionAI - 文档领域的ChatGPT,一款 AI 加持的在线文档编辑和管理工具 作为国际领先的在线文档编辑和管理工具,Notion受到了广大用户的欢迎,尤其是程序员们。它不仅支持笔记、编码等基本的在线文档功能,还支持团队协作、项…

简单XXE漏洞理解以及在实战中演练【网络安全】

1.概念 XXE(XML External Entity Injection) 全称为 XML 外部实体注入。这是一个注入漏洞,强调利用点是外部实体 ,将注意力集中于外部实体中,而不要被 XML 中其他的一些名字相似的东西扰乱了思维,如果能注入 外部实体并且成功解析…

基于springboot实现留守儿童爱心网站平台【源码+论文】分享

基于springboot实现留守儿童爱心网站演示开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包&…

CS-Stdio Display Builder

Display Builder 1) 操作界面编辑器和Runtime 2)在EPICS edd/dm, medm, edm, ...想法上构建 3)与CS-Studio BOY兼容性非常好 4)大约2015年在CS-Stdio/Eclipse中开始,现在在CS-Studio/Phoebus中 5) 从209年以Web Runtime获取。…

UG/NX二次开发实例流程样例(nx1980+vs2019)

接上一篇文章《UG/NX二次开发环境配置方法(nx1980vs2019)》,这一篇文章我们将详细讲述,如何开发一个具体的功能——根据用户输入的数据,在原点处创建一个指定大小的立方体。 由于本功能还涉及到nx的一些基本操作,所以这里先讲一下…

HTB-Stocker

HTB-Stocker信息收集开机提权信息收集 先看80端口。 没有让人眼前一亮的目录。 但是有子域名。 子域名是一个登录功能。 对其进行简单的sql注入测试,发现并不存在sql注入,尝试非sql注入方法绕过登录,NoSQL。经过测试,使用json格式…

【分布式】分布式锁

目录一、分布式锁介绍二、基于 Redis 实现分布式锁1. 如何基于 Redis 实现一个最简易的分布式锁?2.为什么要给锁设置一个过期时间?3. 如何实现锁的优雅续期?4. 如何实现可重入锁?一、分布式锁介绍 单机多线程: 在 Jav…