如何编写一个多线程、非阻塞的python代码

news2024/11/15 20:52:26

一、【写在前面】

最近csdn每天写两篇文章有推广券,趁这个机会写一个python相关的文章吧。

一般我们的任务都可以分为计算密集型任务和IO密集型任务。

python因为全局GIL锁的存在,任何时候只有一个python线程在运行,所以说不能利用多核CPU的优势,这意味着python做计算密集型任务不是很合适。如果提升多核能力,使用multiprocess库或者其他语言写的库

但是在IO密集型任务中,在对速度和效率要求比较高的场景中,我们可以将python的多线程功能用起来。但是多线程必定bug多,这个是不可避免的,所以笔者也只敢在操作影响不大的地方写多线程

这篇文章写一个尽可能通用的python多线程非阻塞的代码示例

二、【名词解释】

1. 多线程

一个进程中可以有多个线程,好比饭店如果只有一个人,炒菜端菜都是一个人干,这就是单线程;

一个饭店有人切菜有人炒菜有人端菜,这就是三线程。

2. 线程之间的通信

而切菜的人把菜丢给炒菜的人,炒菜的人做好丢给端菜的人,这个过程叫做线程之间的通信

3. 线程阻塞

如果切菜的人是个浑浊懵愣的货,切完一个菜之后,厨师没有将菜收走,案板满了。这个切菜的人不愿意干活了,这就是阻塞。

4. 线程池

饭店老板非常有钱,每次有新的工作都会重新招一个人来干,这就叫创建新的线程。

饭店老板如果比较精明,有了新活都抓饭店里闲着的人干,而不招新的人,这就叫线程池。

5. 锁

饭店里只有一个卫生间,如果大家一起上卫生间会有人害羞而尿不出来。所以在员工上卫生间的时候需要加锁。程序中一般是在访问公共变量的时候需要加锁。

6. 线程导致的主程序退出

切菜的师傅切了个炸弹,然后厨师没有确认直接开炒,整个饭店都炸掉了。一般来说线程崩溃就崩溃了,但是如果主程序的某个流程是依赖线程结果的,那么线程崩溃就会把主程序带崩。

三、【代码编写】

这段代码是针对多台机器,每台机器的任务类似的一个多线程的主函数。照着这个往里塞东西就行

import time
import threading
from concurrent.futures import ThreadPoolExecutor

def func1():
    pass

def func2():
    pass

def func3():
    pass

if __name__ == "__main__":
    # init global vars
    vars_dict = {}
    futures = {}
    
    # init locker 线程共用的变量要加锁否则会有奇奇怪怪的问题
    vars_dict_lock = threading.Lock()
    futures_lock = threading.Lock()
    
    # machine list 考虑有机器无法连接的情况
    Machine_List = ['machine1','machine2','machine3','cant_connected_machine']
    
    # prometheus metrix init 针对每个机器都有的变量,避免冗余代码可以这样初始化
    for host in Machine_List:
        ## trading flag monitor below
        vars_dict[f'var1_{host}']  = 'var1'
        vars_dict[f'var2_{host}']= 'var2'
        ## end trading flag mon
        
    # 定义任务函数映射
    task_functions = {
        'describe for func1': func1,
        'describe for func2': func2,
        'describe for func3':func3
    }

    # multi thread task 线程池 10线程
    with ThreadPoolExecutor(max_workers=10) as executor:
        while True:
            with futures_lock:  # 每次操作公共变量需要操作锁
                for host in Machine_List:
                    # 分别为每个任务创建一个唯一的键
                    for task_name, task_func in task_functions.items():
                        task_key = f"{task_name}_{host}"
                        # 如果线程没有创建或没有完成,防止没跑完就起新的
                        if task_key not in futures or futures[task_key].done():
                            futures[task_key] = executor.submit(task_func, host)
                time.sleep(30)
    

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于人工智能技术开发的一种医疗诊断工具:智慧3D导诊系统源码

概述 智能导诊基于医疗 AI 、自然语言处理技术,覆盖导诊、智能问答、科普宣教等就医服务;智能导诊通过人体图、症状列表等形式进行疾病自测,快速推荐就诊科室、医生推荐。产品可应用于微信线上挂号、互联网医院、区域平台等场景中&#xff0…

【搜索核心技术】经典搜索核心算法:BM25及其变种

随着基于检索增强的生成(Retrieval-Augmented Generation—RAG)逐渐成为当前大模型落地方案的主流选择,搜索技术在这一过程中扮演着至关重要的角色。然而,仅依赖向量相似性检索往往无法达到理想的效果。因此,为了进一步…

计算机网络之http状态码和https

目录 HTTP协议 TCP/IP协议 TCP/IP的分层管理 各个协议和HTTP之间的关系 了解并区分URI和URL 返回结果的HTTP状态码 2XX 成功 2.1 200 ok 2.2 204 No Content 2.3 206 Partial Content 3xx表示重定向 3.1 301 Moved Permanently 3.2 302 Found 3.3 303 See …

探索全光网技术 | 全光网络技术方案选型建议二 (宿舍场景)

目录 一、场景设计需求二、宿舍场景拓扑三、部署方式四、产品相关规格说明五、方案优势 注:本文章参考资料为:华三官方资料 - “新华三全光网络3.0解决方案(教育)”与 锐捷官方资料 - “【锐捷】高校极简以太全光3.X方案设计(V1.3…

pinecone向量库的介绍和基本使用(增删改查)

本文来自于【向量库】pinecone向量库的介绍和基本使用(增删改查) Pinecone是一个实时、高性能的向量数据库,专为大规模向量集的高效索引和检索而设计。它提供亚秒级的查询响应时间,确保用户可以迅速获取所需信息。Pinecone采用高…

SAP与九恒星资金系统集成案例(医药行业)

一、项目环境 江西某药业有限公司是一家以医药产业为主营、资本经营为平台的大型民营企业集团。公司成立迄今,企业经营一直呈现稳健、快速发展的态势集团总销售额超40亿元。 为了帮助企业更好的进行资金流、结算、资金调度和运作管理、风险控制,济民…

计算机毕业设计选题推荐-篮球馆会员信息管理系统-Java/Python项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

前端初期知识点回顾

1.跳转:其中target“_blank”意思是跳转会新标签页打开 2.锚点定位:点击文字跳转到对应页面 3:表单 单元格合并 4.input属性变化 前期vue样式 5.画原神: 6.画学生管理系统: 购物车升序降序 累加函数 保留两位小数点 删…

2023年亚太杯A题:果园采摘机器人的图像识别,一二题(题目代码及结果)

问题一:基于附件1中提供的可收获苹果的图像数据集,提取图像特征,建立数学模型,计算每幅图像中的苹果的数量,并绘制附件1中所有苹果的分布直方图。 对于自动采摘机器人,首要的能力就是识别出苹果对象&#…

K3 BOS单据获取制单人工号

新建BOS单据,打印时有时不想在单据上体现制单人姓名,只要打印出工号就行了 新建时,在单据头增加一个“制单人工号”的字段,字段名一定要设置成"FBillerno", 然后在插件中增加资源中的DLL 效果 套打单据中的…

爬虫:jsonpath模块及腾讯招聘数据获取

目录 jsonpath模块 腾讯招聘数据获取 jsonpath模块 # pip install jsonpath -i https://pypi.tuna.tsinghua.edu.cn/simple import jsonpathdata {"store": {"book":[{"category": "reference","author": "Nigel Ree…

电影票竞价系统:揭开神秘代码的面纱

电影票的购买方式也在不断革新。全民邀约电影票竞价系统就是这样一个创新的购票模式。今天,就让我们一起探索这个系统背后的代码秘密,看看竞价购票的代码是如何编写的。 电影票竞价系统的魅力 电影票竞价系统为广大影迷提供了一种全新的购票体验。通过该…

【计算机方向】中科院一区TOP顶刊对比!国人发文友好,“又好又水”!

今天小编带来计算机方向期刊对比,到底那本期刊才是你的“心尖宠”? 速看!为你的心上刊打Call! 这两本期刊,每个学者主观评价不同。 两本期刊含金量到底如何呢? 今天就跟着小编一起来了解下吧!…

FB03 界面新增自定义字段(在业务范围gsber之后)

两个界面都是 一个screen 是1002 一个是1007 两个都要改 代码控制显示 输入 MODULE FRM_MDF_SCREEN OUTPUT.DATA:lmblnr TYPE matdoc-MBLNR.DATA:lmjahr TYPE matdoc-MJAHR.FIELD-SYMBOLS:<FS_MBLNR> TYPE matdoc-MBLNR,<FS_MJAHR> TYPE ANY,<FS_action>…

华为od机试真题:求幸存数之和(Python)

2024华为OD机试&#xff08;C卷D卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 给一个正整数列nums&#xff0c;一个跳数jump&#xff0c;及幸存数量left。运算过程为:从索引为0的位置开始向后跳&#xff0c;中间跳过 J 个数字&#xff0c;命中索引为 J1的数…

private DiscoveryClient discoveryClient 爆红

private DiscoveryClient discoveryClient 爆红 大部分情况是因为导错了包&#xff0c;导成了下面的包 import com.netflix.discovery.DiscoveryClient; 但有个特殊情况导包没有导错&#xff0c;discoveryClient依然爆红 import org.springframework.cloud.client.discovery…

软考系统架构师--第2章 操作系统-2.1 操作系统的类型与结构

目录 第2章 操作系统 2.1 操作系统的类型与结构 2.1.1 操作系统的定义 2.1.2 操作系统分类 第2章 操作系统 本章主要介绍操作系统的基本概念及其形成、发展历史和主要类型&#xff0c;并指出操作系统的 5 大管理功能。掌握操作系统原理的关键在于深入理解“一个观点、两条…

宏定义和内联函数的区别?

在C编程中&#xff0c;宏定义和内联函数都是常用的代码优化方法。它们可以在编译时将代码进行优化&#xff0c;提高程序的执行效率。但是&#xff0c;它们的实现方式和使用方法有所不同。下面将详细介绍宏定义和内联函数的区别。 一、宏定义 宏定义是一种简单的代码替换方式。…

SpringCloud+Vue3一个字段多个存储以及回显

♥️作者&#xff1a;小宋1021 &#x1f935;‍♂️个人主页&#xff1a;小宋1021主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识&#xff0c;和大家一起努力呀&#xff01;&#xff01;&#xff01; &#x1f388;&#x1f388;加油&#xff01; 加油&#xff01…

uni-app便携式蓝牙打印机esc指令改成vue3中使用

1、前言&#xff1a; 之前小程序是用vue2写的&#xff0c;现在要改成vue3&#xff0c;由于不能使用require导入js文件&#xff0c;所以vue2打印中使用到的文件需要改成inport 2、需要改的文件目录 主要是修改这三个文件&#xff0c;把require导入改成import 3、esc.js文件…