【Python】thread使用
目录
- 1、Condition条件变量使用
- 2、event通信
- 3、Semaphore信号量使用
- 4、setDaemon设置守护线程
- 5、threadPool_map使用
- 6、threadPool使用
- 7、threadingTimer
1、Condition条件变量使用
# encoding:utf-8
'''Condition 提供了一种多线程通信机制,
假如线程 1 需要数据,那么线程 1 就阻塞等待,
这时线程 2 就去制造数据,线程 2 制造好数据后,
通知线程 1 可以去取数据了,然后线程 1 去获取数据。'''
import threading
import time
con = threading.Condition()
meat_num = 0def thread_consumers(): # 条件变量 condition 线程上锁con.acquire()# 全局变量声明关键字 globalglobal meat_num# 等待肉片下锅煮熟con.wait()while True:print("我来一块肉片...")meat_num -= 1print("剩余肉片数量:%d" % meat_num)time.sleep(0.5)if meat_num == 0:# 肉片吃光了,通知老板添加肉片print("老板,再来一份老肉片...")con.notify()# 肉片吃光了,等待肉片con.wait()# 条件变量 condition 线程释放锁con.release()def thread_producer(): # 条件变量 condition 线程上锁con.acquire() # 全局变量声明关键字 globalglobal meat_num# 肉片熟了,可以开始吃了meat_num = 10print("肉片熟了,可以开始吃了...")con.notify()while True:# 阻塞函数,等待肉片吃完的通知con.wait()meat_num = 10# 添加肉片完成,可以继续开吃print("添加肉片成功!当前肉片数量:%d" % meat_num)time.sleep(1)con.notify()con.release()if __name__ == '__main__':t1 = threading.Thread(target=thread_producer)t2 = threading.Thread(target=thread_consumers)# 启动线程 -- 注意线程启动顺序,启动顺序很重要t2.start()t1.start()# 阻塞主线程,等待子线程结束t1.join()t2.join()print("程序结束!")'''
输出结果:
肉片熟了,可以开始吃了...
我来一块肉片...
剩余肉片数量:9
我来一块肉片...
剩余肉片数量:8
我来一块肉片...
剩余肉片数量:7
我来一块肉片...
剩余肉片数量:6
我来一块肉片...
剩余肉片数量:5
我来一块肉片...
剩余肉片数量:4
我来一块肉片...
剩余肉片数量:3
我来一块肉片...
剩余肉片数量:2
我来一块肉片...
剩余肉片数量:1
我来一块肉片...
剩余肉片数量:0
老板,再来一份老肉片...
添加肉片成功!当前肉片数量:10
我来一块肉片...
剩余肉片数量:9
我来一块肉片...
剩余肉片数量:8
我来一块肉片...
剩余肉片数量:7
.............
'''
2、event通信
# encoding:utf-8
"""用于线程间的通信,藉由发送线程设置的信号,
若信号为True,其他等待的线程接受到信好后会被唤醒。
提供 設置信号 event.set(), 等待信号event.wait(), 清除信号 event.clear() 。"""import threading
import time
def thread_first_job():global a# 线程进入等待状态print("Wait…")event.wait()for _ in range(3):a += 1print("This is the first thread ", a)
a = 0
# 创建event对象
event = threading.Event()
first_thread = threading.Thread(target=thread_first_job)
first_thread.start()
time.sleep(3)
# 唤醒处于等待状态的线程
print("Wake up the thread…")
event.set()
first_thread.join()
# ====== output ======
# Wait...
# Wake up the thread...
# This is the first thread 1
# This is the first thread 2
# This is the first thread 3
3、Semaphore信号量使用
# encoding:utf-8
# -*- coding:utf-8 -*-
import threading
import time
# Semaphore 跟 Lock 类似,但 Semaphore 多了计数器的功能,可以指定允许个数的线程同时执行。sem = threading.Semaphore(3)class DemoThread(threading.Thread):def run(self):print('{0} is waiting semaphore.'.format(self.name))sem.acquire()print('{0} acquired semaphore({1}).'.format(self.name, time.ctime()))time.sleep(5)print('{0} release semaphore.'.format(self.name))sem.release()if __name__ == '__main__':threads = []for i in range(4):threads.append(DemoThread(name='Thread-' + str(i)))for t in threads:t.start()for t in threads:t.join()
4、setDaemon设置守护线程
"""若希望在主线程执行完毕后,
不管其他的Thread是否已执行完毕,
都强制跟主线程一起结束,
setDaemon()必须写在start() 之前,预设为 False。"""import time
import threadingdef test():while True:print(threading.currentThread())time.sleep(1)if __name__ == '__main__':t1 = threading.Thread(target=test)t1.setDaemon(True)t1.start()t2 = threading.Thread(target=test)t2.setDaemon(True)t2.start()
5、threadPool_map使用
# encoding:utf-8
# 线程池可以控制并发多线程的数量,不会导致系统崩溃from concurrent.futures import ThreadPoolExecutor
import threading
import time# 定义一个准备作为线程任务的函数
def action(max):my_sum = 0for i in range(max):print(threading.current_thread().name + ' ' + str(i))my_sum += ireturn my_sum# 创建一个包含2条线程的线程池
# pool = ThreadPoolExecutor(max_workers=2)
# # 向线程池提交一个task, 50会作为action()函数的参数
# future1 = pool.submit(action, 50)
# # 向线程池再提交一个task, 100会作为action()函数的参数
# future2 = pool.submit(action, 100)
# # 判断future1代表的任务是否结束
# print(future1.done())
# time.sleep(3)
# # 判断future2代表的任务是否结束
# print(future2.done())
# # 查看future1代表的任务返回的结果 阻塞
# print(future1.result())
# # 查看future2代表的任务返回的结果 阻塞
# print(future2.result())
# # 关闭线程池
# pool.shutdown()# ancel():取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回 False;否则,程序会取消该任务,并返回 True。
# cancelled():返回 Future 代表的线程任务是否被成功取消。
# running():如果该 Future 代表的线程任务正在执行、不可被取消,该方法返回 True。
# done():如果该 Funture 代表的线程任务被成功取消或执行完成,则该方法返回 True。
# result(timeout=None):获取该 Future 代表的线程任务最后返回的结果。如果 Future 代表的线程任务还未完成,该方法将会阻塞当前线程,其中 timeout 参数指定最多阻塞多少秒。
# exception(timeout=None):获取该 Future 代表的线程任务所引发的异常。如果该任务成功完成,没有异常,则该方法返回 None。
# add_done_callback(fn):为该 Future 代表的线程任务注册一个“回调函数”,当该任务成功完成时,程序会自动触发该 fn 函数。
# 如果程序不希望直接调用 result() 方法阻塞线程,则可通过 Future 的 add_done_callback() 方法来添加回调函数,该回调函数形如 fn(future)。当线程任务完成后,程序会自动触发该回调函数,并将对应的 Future 对象作为参数传给该回调函数。
def spider(page):time.sleep(page)print(f"crawl task{page} finished tread_name"+threading.currentThread().name)return page
# 该方法的功能类似于全局函数 map(),区别在于线程池的 map() 方法会为 iterables 的每个元素启动一个线程,以并发方式来执行 func 函数。这种方式相当于启动 len(iterables) 个线程,井收集每个线程的执行结果。
with ThreadPoolExecutor(max_workers=2) as pool:# map可以保证输出的顺序, submit输出的顺序是乱的.print ("start processes...")res = pool.map(spider, [0, 1, 2, 3])print("{}" .format(res))print('------done------')
6、threadPool使用
# encoding:utf-8
# 线程池可以控制并发多线程的数量,不会导致系统崩溃from concurrent.futures import ThreadPoolExecutor
import threading
import time# 定义一个准备作为线程任务的函数
def action(max):my_sum = 0for i in range(max):print(threading.current_thread().name + ' ' + str(i))my_sum += ireturn my_sum# 创建一个包含2条线程的线程池
# pool = ThreadPoolExecutor(max_workers=2)
# # 向线程池提交一个task, 50会作为action()函数的参数
# future1 = pool.submit(action, 50)
# # 向线程池再提交一个task, 100会作为action()函数的参数
# future2 = pool.submit(action, 100)
# # 判断future1代表的任务是否结束
# print(future1.done())
# time.sleep(3)
# # 判断future2代表的任务是否结束
# print(future2.done())
# # 查看future1代表的任务返回的结果 阻塞
# print(future1.result())
# # 查看future2代表的任务返回的结果 阻塞
# print(future2.result())
# # 关闭线程池
# pool.shutdown()# ancel():取消该 Future 代表的线程任务。如果该任务正在执行,不可取消,则该方法返回 False;否则,程序会取消该任务,并返回 True。
# cancelled():返回 Future 代表的线程任务是否被成功取消。
# running():如果该 Future 代表的线程任务正在执行、不可被取消,该方法返回 True。
# done():如果该 Funture 代表的线程任务被成功取消或执行完成,则该方法返回 True。
# result(timeout=None):获取该 Future 代表的线程任务最后返回的结果。如果 Future 代表的线程任务还未完成,该方法将会阻塞当前线程,其中 timeout 参数指定最多阻塞多少秒。
# exception(timeout=None):获取该 Future 代表的线程任务所引发的异常。如果该任务成功完成,没有异常,则该方法返回 None。
# add_done_callback(fn):为该 Future 代表的线程任务注册一个“回调函数”,当该任务成功完成时,程序会自动触发该 fn 函数。
# 如果程序不希望直接调用 result() 方法阻塞线程,则可通过 Future 的 add_done_callback() 方法来添加回调函数,该回调函数形如 fn(future)。当线程任务完成后,程序会自动触发该回调函数,并将对应的 Future 对象作为参数传给该回调函数。with ThreadPoolExecutor(max_workers=2) as pool:# 向线程池提交一个task future_list = []for i in range(0, 2):tmp_future = pool.submit(action, (i + 1) * 50)future_list.append(tmp_future)def get_result(future):print(future.result())# 为future提供回调函数for future in future_list:future.add_done_callback(get_result)print('------done------')
7、threadingTimer
# python中使用threading.Timer作为定时函数
# 参考:https://www.pynote.net/archives/1783
# https://docs.python.org/3/library/threading.html#timer-objects
# 设置一个延迟时间,当经过了这么多时间后,某个函数被调用;如果希望反复调用,就需要编程在被调用的函数中,再次实现这个延迟一段时间调用函数的代码# threading.Timer创建的是一个线程!这个细节要注意,定时器基本上都是在线程中执行。# 如果定时器内的代码执行时间超过了定时器的间隔,怎么办?看来在python中,这个问题是不存在的,下一次定时器的计时开始,会在定时器代码执行完后才开始。
import time
import threadingdef createTimer():t = threading.Timer(2, repeat)t.start()def repeat():print('Now:', time.strftime('%H:%M:%S',time.localtime()))createTimer()createTimer()
相关文章:
【Python】thread使用
目录1、Condition条件变量使用2、event通信3、Semaphore信号量使用4、setDaemon设置守护线程5、threadPool_map使用6、threadPool使用7、threadingTimer1、Condition条件变量使用 # encoding:utf-8 Condition 提供了一种多线程通信机制, 假如线程 1 需要数据&#…...
计网传输层协议:UDP和TCP
文章目录一. 应用层和传输层的联系二. UDP协议三. TCP协议1. TCP报头介绍2. TCP实现可靠传输的核心机制2.1 确认应答2.2 超时重传3. 连接管理(三次握手, 四次挥手)3.1 建立连接(三次握手)3.2 断开连接(四次挥手)4. 滑动窗口5. 流量控制6.拥塞控制7. 延时应答8. 捎带应答9. 面向…...
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
文章目录1 Socket讲解2 基于Socket的TCP编程3 客户端Socket的工作过程包含以下四个基本的步骤3.1 客户端创建Socket对象4 服务器程序的工作过程包含以下四个基本的步骤:4.1 服务器建立ServerSocket对象5 案例实现 客户端和服务端通信5.1 代码实现5.2 实现结果6 更多…...
Java中print和println的区别
1 问题在最开始学习Java的时候学到soutenter键可以输出结果,显示的是System.out.println();而在Python中是直接使用print。那么在Java中print和println有什么区别?2 方法Print输出会自动将括号中的内容转换成字符串输出,如果括号中…...
RocketMq使用规范(纯技术和实战建议)
概述: 使用规范主要从,生产、可靠性、和消费为轴线定义使用规范;kafka使用核心:削峰、解耦、向下游并行广播通知(无可靠性保证)和分布式事务,本规范仅从削峰、解耦、向下游并行广播通知论述&am…...
matlab离散系统仿真分析——电机
目录 1.电机模型 2.数字PID控制 3.MATLAB数字仿真分析 3.1matlab程序 3.2 仿真结果 4. SIMULINK仿真分析 4.1simulink模型 4.2仿真结果 1.电机模型 即: 其中:J 0.0067;B 0.10 2.数字PID控制 首先我们来看一下连续PID࿱…...
一文学会进程控制
目录进程的诞生fork函数fork的本质fork的常规用法fork调用失败的原因进程的死亡进程退出的场景常见的进程退出方法正常终止(代码跑完)echo $?main函数返回调用exit调用_exitexit和_exit的区别进程等待进程等待的重要性进程等待的函数waitwaitpid进程退出…...
5.2 BGP水平分割
5.2.2实验2:BGP水平分割 1. 实验目的 熟悉BGP水平分割的应用场景掌握BGP水平分割的配置方法 2. 实验拓扑 实验拓扑如图5-2所示: 图5-2:BGP水平分割 3. 实验步骤 (1)配置IP地址 R1的配置 <Huawei>…...
华为OD机试 - TLV 编码 | 备考思路,刷题要点,答疑 【新解法】
最近更新的博客 【新解法】华为OD机试 - 关联子串 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 停车场最大距离 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 任务调度 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试…...
【C语言每日一题】——猜名次
【C语言每日一题】——猜名次😎前言🙌猜名次🙌解题思路分享:😍解题源码分享:😍总结撒花💞😎博客昵称:博客小梦 😊最喜欢的座右铭:全神…...
Agilent E4982A、Keysight E4982A、LCR 表,1 MHz 至 3 GHz
Agilent E4982A、Keysight E4982A、HP E4982A LCR 表,1 MHz 至 3 GHz 产品概览 KEYSIGHT E4982A(安捷伦) Keysight E4982A LCR 表为需要高频(1 MHz 至 3 GHz)阻抗测试的无源元件制造行业提供一流的性能,…...
SAP 系统的配置传输
在SAP项目的实施过程中,经常会遇到关于配置传输的问题。即我们在某个client下面做系统配置,配好了之后再传到其他系统之中。 配置传输分为两种情况:同服务器配置传输,异服务器配置传输。同服务器配置传输: 在DEV配置cl…...
华为OD机试 - 喊七(Python)
喊七 题目 喊 7,是一个传统的聚会游戏, N 个人围成一圈,按顺时针从1 - 7编号, 编号为1的人从1开始喊数, 下一个人喊得数字是上一个人喊得数字+1, 但是当将要喊出数字7的倍数或者含有7的话, 不能喊出,而是要喊过。 假定N个人都没有失误。 当喊道数字k时, 可以统计每…...
Docker下快速搭建RabbitMQ单例及集群
引子生命在于折腾,为上数据实时化用到了消息传送的内容,当时也和总公司人员商量选型,kafka不能区分分公司就暂定用了RbtMQ刚好个人也在研究容器及分布式部署相关内容就在docker上实践单机 docker(要想快 先看问题 避免踩坑&#x…...
python代码写开心消消乐
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放,树高千尺,落叶归根人生不易,人间真情 目录 一.python是什么 二.游戏代码效果呈现 三.主代...
【郭东白架构课 模块一:生存法则】09|法则四:为什么要顺应技术的生命周期?
你好,我是郭东白。今天我们来讲架构师的第四条生存法则,那就是尊重技术的生命周期。 人类的各种活动都要遵循事物的客观生命周期。不论是农业社会种田打渔,还是资本社会投资创业,行动太早或太晚,都会颗粒无收。技术也…...
Linux之进程控制
一.进程创建 1.1 fork函数 我们创建进程的方式有./xxx和fork()两种 在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。 #include <unistd.h> pid_t fork(void); 返回值:自进程…...
SpringBoot社区版专业版带你配置热部署
💟💟前言 友友们大家好,我是你们的小王同学😗😗 今天给大家打来的是 SpringBoot社区版专业版带你配置热部署 希望能给大家带来有用的知识 觉得小王写的不错的话麻烦动动小手 点赞👍 收藏⭐ 评论…...
影响AFE采样精度的因素有哪些?
**AFE(Analog Front End)**是模拟前端电路的缩写,它是模拟信号传感器和数字信号处理器之间的连接点。AFE采样精度是指模拟信号被数字化后的准确度,对于很多电子设备来说,这是一个至关重要的性能指标。本文将介绍影响AF…...
mysqlbackup备份报error:redo log was overwritten
问题原因 备份时redo log被覆盖 解决方案 方法1:增加innodb_log_file_size、innodb_log_files_in_group大小,需要重启数据库 vi my.cnf innodb_log_file_size 2G innodb_log_files_in_group 4 方法2: 动态配置redo log archive,不需要重启…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
