自动化测试提速必备 - 并发编程


在自动化测试领域,多线程和多进程技术被广泛应用于提高测试的执行效率和性能。通过并发运行测试用例,可以显著缩短测试周期,特别是在面对大量测试用例或者需要在多个环境中进行测试时尤为重要。 


 

在实际的自动化测试中,我们经常碰到类似的需求:

  • 100条自动化测试用例,采用默认的依次执行方式,所需要的时间竟然高达1个小时,我们需要想办法对其进行时间上的优化

  • App自动化测试中,我们需要同时对多台测试机进行同时测试,以满足我们对于兼容性测试的需求

  • 自动化测试中,我们需要额外监控应用程序/测试机的性能(比如CPU、内存的使用情况),监控不能干扰主测试流程

在这个时候往往我们需要使用并发编程的技术-多线程和多进程,通过并发执行测试用例,可以显著缩短自动化测试时间,同时也能实现在多个环境中同时执行测试的效果。

那么到底什么是多进程和多线程,以及什么时候选择多进程什么时候选择多线程呢?

Python多线程

在计算机中线程是执行中的最小单位。一个进程中可以包含多个线程,它们共享进程的资源,包括内存空间和打开的文件。每个线程都有自己的执行路径,可以独立执行任务。线程的创建和管理由操作系统负责,而不同的操作系统可能对线程有不同的实现方式。

Python提供了threading模块来支持多线程编程。通过threading模块,我们可以创建Thread类的实例,并传入一个函数作为线程的执行体。例如:

from threading import Thread
def worker(money):    print("开始干活")    print(f"拿到{money}块工资")
# 通过target指定线程具体执行的工作-传入对应函数,args参数执行传入函数的参数,需要注意这里是元组类型的thread = Thread(target=worker,args=(100,))# 启动线程thread.start()# 等待线程执行结束thread.join()
多线程GIL锁的问题

我们来看以下小案例:

import time
def count(n):    while n > 0:        n -=1
start_time = time.time()count(100000)end_time = time.time()print(end_time-start_time)

该程序在我的四核Intel i5 CPU上执行所需的时间为0.003968954086303711秒

把上述的程序改造成多线程模式:

​​​​​​​

import timefrom threading import Thread
def count(n):    while n > 0:        n -=1
start_time = time.time()# count(100000)t1 = Thread(target=count, args=[100000 // 2])t2 = Thread(target=count, args=[100000 // 2])t1.start()t2.start()t1.join()t2.join()end_time = time.time()print(end_time-start_time)

多线程模式下所需要的时间为:0.005413532257080078秒

此程序中使用了2个线程来执行和上面一样的工作,从结果来看效率没有提高反而降低了。其实这里不管使用多少线程,其结果中效率和2个线程效率几乎一样。

为什么会有这种情况?这一切的罪魁祸首来源于GIL:

全局解释器锁(GIL)是Python解释器中的一个机制,用于保护解释器内部数据结构不受多线程并发访问的影响。GIL确保了在任意时刻只有一个线程在解释器中执行Python字节码。这意味着尽管Python中可以创建多个线程,但在任何给定时刻只有一个线程能够真正执行代码,其他线程会被阻塞。

图片

  • 当线程在运行时,它会持有GIL锁,其他的进程不能持有GIL锁

  • 当线程遇到IO操作时(比如读写磁盘,发送/接收网络数据等)将会释放GIL锁,其他的线程此时可以获取GIL锁

我们可以根据上述知道:即便我们的CPU是多核心,因为Python GIL锁的存在,同一时间只允许执行一个线程,单个时刻也只能使用到1个CPU核心,所以CPU的利用率不高。

多线程适用的场景

在程序运行时候有两种不同类型的计算任务:

CPU密集型计算

CPU密集型计算指的是任务主要耗费CPU资源,而对于其他资源(如内存、磁盘、网络等)的需求相对较少的计算任务。在CPU密集型计算中,程序主要执行大量的计算操作,例如数学运算、图像处理、加密解密、复杂算法等。

IO密集型计算

IO密集型计算指的是任务主要耗费在等待IO操作上,例如磁盘读写、网络通信、数据库查询等。在IO密集型计算中,CPU主要用于处理IO操作的调度和处理。

所以如果是IO密集型计算任务,使用多线程是比较合适的,虽然GIL锁存在导致只能单个线程在CPU内执行,但是在IO处理时不受限制的,IO操作较多时使用多线程依然可以加速任务的执行。

Python多进程

Python中有了多线程,为什么还需要用多进程?

前面我们讲了GIL锁的存在,当多线程遇到了CPU密集型的计算时,反而会降低程序的执行效率

GIL锁同一时间只允许执行一个线程执行,多线程之间还会涉及到上下文切换,上下文切换也需要花费时间

那么什么是多进程呢?

在操作系统中,进程是一个独立运行的程序实例。每个进程都有自己独立的内存空间,一个进程崩溃不会直接影响到其他进程。在多核处理器上,多进程能够实现真正的并行计算,每个进程可以在不同的处理器核心上运行。

Python标准库中的multiprocessing模块能够实现多进程,这个模块提供了与多线程threading模块类似的API。使用multiprocessing,每个Python进程都有自己的Python解释器和内存空间,这样就避开了GIL的限制,能够充分利用多核CPU的计算资源。

​​​​​​​

from multiprocessing import Process
def worker(money):    print("开始干活")    print(f"拿到{money}块工资")
# 通过target指定进程具体执行的工作-传入对应函数,args参数执行传入函数的参数,需要注意这里是元组类型的process = Process(target=worker,args=(100,))# 启动进程process.start()# 等待子进程执行结束process.join()

多进程的主要优势在于能够绕过GIL的限制,利用多核CPU实现真正的并行计算,特别适合处理CPU密集型任务。

其劣势在于运行一个进程消耗的资源比线程多很多,进程间的通讯也是比较复杂(比如需要用到消息队列、管道等机制)

最后总结一句话:对于CPU密集型任务选择多进程,对于IO密集型任务选择多线程。

 

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

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

相关文章

2024年【T电梯修理】考试总结及T电梯修理考试技巧

题库来源:安全生产模拟考试一点通公众号小程序 T电梯修理考试总结考前必练!安全生产模拟考试一点通每个月更新T电梯修理考试技巧题目及答案!多做几遍,其实通过T电梯修理试题及解析很简单。 1、【多选题】修理工陶、陈&#xff0c…

废石颗粒运动理论模型及Python模拟

学者赵国彦等[26]对于废石颗粒运动的理论模型进行做了较为充分的研究,本文在以往研究的基础上对相关推导进行补充修正,并以某金矿充填废石的基本物理性能测试数据为基础,对废石运动理论模型的进行模拟。 4.2.1废石运动理论模型 4.2.1.1废石…

AI大模型探索之路-应用篇10:Langchain框架-架构核心洞察

目录 前言 一、LangChain设计目标 二、LangChain设计之道 三、LangChain典型应用 1、简单的问答Q&A over SQL CSV: 2、聊天机器人Chatbots: 3、总结摘要Summarization: 4、网页爬虫Web scraping: 5、本地知识库(Q&A with RAG): 三、LangChain架构…

数字阅览室-数字图书馆体系的重要补充

数字阅览室(Digital Reading Room)是一种依托现代信息技术,特别是互联网、数字媒体技术和数据库管理技术,为用户提供在线访问、阅读、学习和研究各类数字化文献资源的虚拟空间。它是数字图书馆服务体系中的一个重要组成部分&#…

文库配置异步转换(宝塔)| 魔众文库系统

执行以下操作前提前进入网站根目录,如 cd /www/wwwroot/example.com执行 artisan 命令前请参照 开发教程 → 开发使用常见问题 → 如何运行 /www/server/php/xxx/bin/php artisan xxx 命令 步骤1,生成数据库队列表迁移文件 在执行该步骤前,请…

数据可视化高级技术Echarts(折线图)

目录 一、什么是折线图 二、如何实现 1.基本折线图 2.如何变得平滑只需要定义: smooth 3.如何定义线条的样式 color:设置线的颜色 width:设置线宽 type:设置线的类型 4.如何定义节点样式 symbol symbolSize&#xff1a…

开发着开发着,盘满了

办公电脑突然报家目录不足1G空间了, 使用 Disk Usage Analyzer 工具打开看了下, 微软还真没把我当穷人, 一个vs code给我占了30几个G的空间. 大家可能也遇到这种情况的, 看到真的让人窒息, 以前windows上被VS studio 支配C盘的感觉又回来了. 不过这个ubuntu好处理点, 我该删…

算法打卡day32

今日任务: 1)738.单调递增的数字 2)968.监控二叉树 738.单调递增的数字 题目链接:738. 单调递增的数字 - 力扣(LeetCode) 文章讲解:代码随想录 (programmercarl.com) 视频讲解:贪…

CPU核心数、线程数都是什么意思?

最早,每个物理 cpu 上只有一个核心,对操作系统而言,也就是同一时刻只能运行一个进程/线程。 为了提高性能,cpu 厂商开始在单个物理 cpu 上增加核心(实实在在的硬件存在),也就出现了多核 cpu&…

个人博客项目笔记_07

写文章 写文章需要 三个接口: 获取所有文章类别 获取所有标签 发布文章 1. 所有文章分类 1.1 接口说明 接口url:/categorys 请求方式:GET 请求参数: 参数名称参数类型说明 返回数据: {"success":…

Linux启动流程,常见故障英文总结/Linux学习环境发行版本选择及运行故障(补充)

小编这里对前面文章内容进行补充 1.运维架构人员理解Linux启动流程(对故障进行排查),企业面试面试官让面试者描述Linux启动细节,小编在这篇文章补充以下,制作了图表,有利于大家看懂整个流程 2.对于初学者/老…

14亿美元!德国默克与AI生物科技公司合作;马斯克Neuralink首位脑机接口植入者用意念打游戏;黄仁勋在俄勒冈州立大学开讲

AI for Science 的新成果、新动态、新视角—— 日本第一 IT 公司富士通:生成式 AI 加速药物研发 马斯克:Neuralink 首位脑机接口植入者用「意念」打游戏 默克与 AI 生物科技公司 Caris 达成合作 AI 蛋白质设计服务提供商「天鹜科技」完成数千万元 Pre…

IDEA中使用正则表达式替换时间日期

很多时候需要把系统中的时间替换成当前时间,这是后我们就可以把数据库SQL文件在IDEA中打开,然后使用正则进行替换,下面我们来看下: 1.日期格式:校验yyyy-MM-dd ((([0-9]{3}[1-9]|[0-9]{2}[1-9…

ELK 企业级日志分析 ELFK

一 ELK 简介 ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logstash 和 Kiabana 三个开源 工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。 1 ElasticSearch: 是基于Lucene(一个全文检索引擎的…

golang的引用和非引用总结

目录 概述 一、基本概念 指针类型(Pointer type) 非引用类型(值类型) 引用类型(Reference Types) 解引用(dereference) 二、引用类型和非引用类型的区别 三、golang数据类型…

李沐27_含并行连结的网络GoogLeNet_Inception——自学笔记

Inception块 1.四个路径从不同层面抽取信息,然后在输出通道维合并。 2.有更少的参数个数和计算复杂度(相比于3X3和5X5卷积层) GoogLeNet 1.五个stages,九个inception块 Inception各种后续变种 1.Inception-BN(V2)——使用ba…

【Harbor】harbor.yml详解

目录 前言参数详解hostnameHTTP和HTTPSinternal_tlsharbor_admin_passworddatabasedata_volumestorage_serviceclairtrivyjobservicenotificationchartlog_versionexternal_databaseexternal_redisuaaproxy 前言 网络上对Harbor相关的资料真是少之又少,基本上都是教…

2024mathorcup数学建模A 题思路分析-移动通信网络中 PCI 规划问题

# 1 赛题 A 题 移动通信网络中 PCI 规划问题 物理小区识别码(PCI)规划是移动通信网络中下行链路层上,对各覆盖 小区编号进行合理配置,以避免 PCI 冲突、 PCI 混淆以及 PCI 模 3 干扰等 现象。 PCI 规划对于减少物理层的小区间互相干扰(ICI),增…

STM32程序 关于Semhosting(半主机)和Microlib 以及Printf的关系

一,Keil中Printf导致程序无法运行到Main函数 在Keil中调试STM32程序,编译烧录后,发现程序不能运行,Main函数中点亮LED灯的语句没起作用,说明没有进入Main函数。用Keil调试的时候,虽然设置了Run to main()&…

Docker学习笔记(二):在Linux中部署Docker(Centos7下安装docker、环境配置,以及镜像简单使用)

一、前言 记录时间 [2024-4-6] 前置文章:Docker学习笔记(一):入门篇,Docker概述、基本组成等,对Docker有一个初步的认识 在上文中,笔者进行了Docker概述,介绍其历史、优势、作用&am…