前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【python实操】马上毕业了,你还不懂什么是守护线程、线程、进程?(附12306抢票程序-源代码)

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

作者头像
20岁爱吃必胜客
发布于 2023-03-30 06:58:34
发布于 2023-03-30 06:58:34
66300
代码可运行
举报
文章被收录于专栏:进步集进步集
运行总次数:0
代码可运行
  • 作者:20岁爱吃必胜客(坤制作人),近十年开发经验, 跨域学习者,目前于海外某世界知名高校就读计算机相关专业。
  • 荣誉:阿里云博客专家认证、腾讯开发者社区优质创作者,在CTF省赛校赛多次取得好成绩。
  • 跨领域学习,喜欢摄影、弹吉他、咏春拳。文章深入浅出、语言风趣;爱吃必胜客社区创立者,旨在“发现美 欣赏美

文章目录

⭐️前言

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

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

🌟 进程-process

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

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

🌟 线程-Treading

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

线程组成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
线程id-----当前指令指针------寄存器集合---------堆栈

🌟 守护线程-Deamon Treading

☀️java中的应用

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

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

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

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

☀️python中的应用

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import threading
import time

def 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模块创建和管理线程的示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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():创建一个事件对象,用于线程之间的通信和同步等。

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import threading

# 定义一个共享变量
num = 0

# 创建一个锁对象
lock = threading.Lock()

# 定义一个线程执行的任务函数
def task():
    global num
    for i in range(1000000):
        lock.acquire()
        num += 1
        lock.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模块

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import threading
import time

class Ticket:
    def __init__(self, name, quantity):
        self.name = name
        self.quantity = quantity
        self.lock = threading.Lock()
        
    def buy(self, num):
        self.lock.acquire()
        try:
            if self.quantity >= num:
                self.quantity -= num
                print(f"当前剩余车票:{self.quantity}")
                return True
            else:
                print("余票不足,购票失败")
                return False
        finally:
            self.lock.release()

def worker(name, ticket, num):
    while True:
        if ticket.buy(num):
            print(f"{name} 购买 {num} 张车票成功!")
            break
        else:
            print(f"{name} 正在尝试购买车票中...")
            time.sleep(1)

if __name__ == '__main__':
    t = Ticket("北京-上海", 10)
    threads = []
    for i in range(5):
        name = f"用户{i+1}"
        num = 2
        t1 = 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代码示例。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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] == '':  # 过滤无效车次
        continue
    if trainList[29] == 'Y':  # 判断是否有余票
        print('车次:{},余票数量:{}'.format(trainList[3], trainList[29]))

# 设置查询间隔
time.sleep(10)

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
多线程与多进程 | 多线程
是计算机中已运行程序的实体。进程与程序不同,程序本身只是指令、数据及其组织形式的描述,进程才是程序的真正运行的实体。
数据STUDIO
2021/06/24
1K0
Python线程锁
多线程的优势: 可以同时运行多个任务 但是当多个线程同时访问共享数据时,可能导致数据不同步,甚至错误! so,不使用线程锁, 可能导致错误 购买车票--线程锁 [root@~]# cat test.py  #-*- coding:utf-8 -*- import threading import time   tickets = range(1,10)   def buy_ticket(station):     while  True: mylock.acquire()      #加线程锁 if len
py3study
2020/01/07
5620
Python - 多线程
**线程(Thread)**也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。
为为为什么
2022/08/04
7180
python多线程详解
②每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
全栈程序员站长
2022/09/06
1.6K0
python多线程详解
python多线程菜鸟教程_python实现多线程有几种方式
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说python多线程菜鸟教程_python实现多线程有几种方式,希望能够帮助大家进步!!!
Java架构师必看
2022/07/06
7790
Python进程与线程及GIL(全局解释
程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种一个程序在一个数据集上的一次动态执行过程就称之为进程。程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本;进程是程序的一次执行活动,属于动态概念。进程一般由程序、数据集、进程控制块三部分组成。
py3study
2020/01/10
9120
Python基础教程(二十一):多线程
在计算机编程中,多线程是一种让程序能够同时执行多个任务的技术,这对于提升程序的响应速度和效率尤为重要。Python,作为一门广泛应用的高级编程语言,也提供了多线程的支持。然而,由于全局解释器锁(GIL)的存在,Python的多线程在CPU密集型任务上的优势并不明显,但在IO密集型任务中却能大放异彩。本文将深入探讨Python多线程的原理、使用方法以及实战案例,帮助你更好地理解并利用这一特性。
用户11147438
2024/06/17
1870
8.0 Python 使用进程与线程
python 进程与线程是并发编程的两种常见方式。进程是操作系统中的一个基本概念,表示程序在操作系统中的一次执行过程,拥有独立的地址空间、资源、优先级等属性。线程是进程中的一条执行路径,可以看做是轻量级的进程,与同一个进程中的其他线程共享相同的地址空间和资源。
王 瑞
2023/08/14
3550
11.python线程
基本概念 1.进程 定义:  进程就是一个程序在一个数据集上的一次动态执行过程。 组成:  进程一般由程序、数据集、进程控制块三部分组成。 程序:  我们编写的程序用来描述进程要完成哪些功能以及如何完成; 数据集: 则是程序在执行过程中所需要使用的资源; 进程控制块: 用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志 2.线程     线程的出现是为了降低上下文切换的消耗,提高系统的并发性,并突破一个进程只能干一样事的缺陷,使到进程
zhang_derek
2018/04/11
5900
python3.9多线程_python多线程没用
线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行
全栈程序员站长
2022/09/19
1.1K0
python3.9多线程_python多线程没用
python多线程
1 多进程 # 多进程, import os import time from multiprocessing import Process # 启动时必须在 if __name__ 判断下,windows 必须,其他 无限制 # ================================================= # def func(args): # print("子进程:",os.getpid()) # print("子进程的父进程:",os.getppid()) #
Dean0731
2020/05/08
1.7K0
Python多线程(下)
上节课我们分享了Python多线程的基础语法,以及GIL的相关概念,这节课我们重点讲解一个知识点,就是多线程的数据安全问题。
罗罗攀
2022/01/11
3450
Python多线程(下)
一文读懂Python多线程
1、线程和进程 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。 假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就
石晓文
2018/04/11
1.3K0
一文读懂Python多线程
Python 爬虫新手教程:12306抢票,开源代码!
今天就和大家一起来讨论一下python实现12306余票查询(pycharm+python3.7),一起来感受一下python爬虫的简单实践 我们说先在浏览器中打开开发者工具(F12),尝试一次余票的查询,通过开发者工具查看发出请求的包
一墨编程学习
2019/08/06
3.5K1
Python 爬虫新手教程:12306抢票,开源代码!
Python 多线程与多进程
原文地址:http://www.cnblogs.com/whatisfantasy/p/6440585.html
Dar_Alpha
2018/10/09
6230
Python多线程、阻塞线程、线程同步和守护线程实例详解
1、主线程是程序本身,看不到的,主线程和子线程没有依赖关系,同步执行的,若主线程先执行完,会等子线程执行完毕,程序结束
王大力测试进阶之路
2020/02/10
4.9K0
python笔记9-多线程Threading之阻塞(join)和守护线程(setDaemon)
前言 今天小编YOYO请xiaoming和xiaowang吃火锅,吃完火锅的时候会有以下三种场景: - 场景一:小编(主)先吃完了,xiaoming(客)和xiaowang(客)还没吃完,这种场景会导致结账的人先走了,剩下两个小伙伴傻眼了。。。 - 场景二:小编(主)先吃完了,xiaoming和xiaowang还没吃饱,一起结账走人。 - 场景三:小编(主)先等xiaoming和xiaowang吃饱了,小编最后结账一起走人。 一、 主线程与子线程 场景一:主线程已经结束了,子线程还在跑 1.我们把threa
上海-悠悠
2018/04/08
1.1K0
python笔记9-多线程Threading之阻塞(join)和守护线程(setDaemon)
Python学习(九)---- python中的线程
原文地址: https://blog.csdn.net/fgf00/article/details/52773459 编辑:智能算法,欢迎关注! 上期我们一起学习了python中的类的相关知识
智能算法
2018/10/08
9370
Python学习(九)---- python中的线程
python爬12306并买票_python开发12306抢票
1.本项目只是一个练习,熟悉python爬虫技术,没有任何用途 2.最后运行的结果有时候会成功,有时候会显示错误界面,如下图所示。因为12306怎么可能允许你一直爬它呢
全栈程序员站长
2022/11/17
2.1K0
python爬12306并买票_python开发12306抢票
守护线程和非守护线程的区别以及用法_python多线程守护进程
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/03
6330
相关推荐
多线程与多进程 | 多线程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档