【操作系统】为什么在Windows系统上tqdm跟print函数两者不是同步输出的呢?

2024-02-02 08:20

本文主要是介绍【操作系统】为什么在Windows系统上tqdm跟print函数两者不是同步输出的呢?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 问题描述

今天在学习tqdm的时候,遇到一个问题,就是我发现trange的输出跟主线程的print函数不是同步输出的
我使用的测试代码如下:

import sysfrom tqdm import trangedef main():X = 100for i in trange(X):# for i in trange(X, file=sys.stdout):print(i)for j in range(X):print(j)k = j * iprint("Done🛠️")return 0if __name__ == '__main__':main()

控制台的输出如下:

# 输出信息很多,这里就只给出了最后几行信息
...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Done🛠️
100%|██████████| 100/100 [00:00<00:00, 3694.12it/s]Process finished with exit code 0

可以看到100%|██████████| 100/100 [00:00<00:00, 3694.12it/s]信息竟然是在Done🛠️之后才输出的,这让我们感觉很奇怪;

2 假设和猜测

(1)猜测:tqdm在其底层实现中是使用子线程进行进度条的打印输出的

也就是,进度条的打印输出是异步进行的,所以才会出现【100%|██████████| 100/100 [00:00<00:00,...]进度条信息在Done🛠️】之后输出的情况;

(2)猜测:tqdm的进度条刷新也是通过end='\r'的设置实现的

我们如此猜测,是因为如果在中途进行print输出的话,就会重复显示进度条;我们使用了如下代码来进行测试:

import sys
from tqdm import trangedef main():X = 10k = 0for i in trange(X, file=sys.stderr):  # 使用默认的stderr输出print(f"Outer loop {i}")for j in range(2000000):k += j * iprint(f"Done🛠️: k = {k}")return 0if __name__ == '__main__':main()

其输出信息如下:

  0%|          | 0/10 [00:00<?, ?it/s]Outer loop 0
Outer loop 120%|██        | 2/10 [00:00<00:00, 11.00it/s]Outer loop 2
Outer loop 340%|████      | 4/10 [00:00<00:00, 10.02it/s]Outer loop 4
Outer loop 560%|██████    | 6/10 [00:00<00:00,  9.67it/s]Outer loop 670%|███████   | 7/10 [00:00<00:00,  9.52it/s]Outer loop 7
Outer loop 890%|█████████ | 9/10 [00:00<00:00,  9.32it/s]Outer loop 9
100%|██████████| 10/10 [00:01<00:00,  9.53it/s]
Done🛠️: k = 89999955000000Process finished with exit code 0

可以看到中途会出现循环过程中的进度条信息;

3 提问备忘

【StackOverflow】Understanding Threading Behavior in tqdm for Progress Bar Updates

这篇关于【操作系统】为什么在Windows系统上tqdm跟print函数两者不是同步输出的呢?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/670073

相关文章

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

Windows Server服务器上配置FileZilla后,FTP连接不上?

《WindowsServer服务器上配置FileZilla后,FTP连接不上?》WindowsServer服务器上配置FileZilla后,FTP连接错误和操作超时的问题,应该如何解决?首先,通过... 目录在Windohttp://www.chinasem.cnws防火墙开启的情况下,遇到的错误如下:无法与

C++中函数模板与类模板的简单使用及区别介绍

《C++中函数模板与类模板的简单使用及区别介绍》这篇文章介绍了C++中的模板机制,包括函数模板和类模板的概念、语法和实际应用,函数模板通过类型参数实现泛型操作,而类模板允许创建可处理多种数据类型的类,... 目录一、函数模板定义语法真实示例二、类模板三、关键区别四、注意事项 ‌在C++中,模板是实现泛型编程

kotlin的函数forEach示例详解

《kotlin的函数forEach示例详解》在Kotlin中,forEach是一个高阶函数,用于遍历集合中的每个元素并对其执行指定的操作,它的核心特点是简洁、函数式,适用于需要遍历集合且无需返回值的场... 目录一、基本用法1️⃣ 遍历集合2️⃣ 遍历数组3️⃣ 遍历 Map二、与 for 循环的区别三、高

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重

Python解析器安装指南分享(Mac/Windows/Linux)

《Python解析器安装指南分享(Mac/Windows/Linux)》:本文主要介绍Python解析器安装指南(Mac/Windows/Linux),具有很好的参考价值,希望对大家有所帮助,如有... 目NMNkN录1js. 安装包下载1.1 python 下载官网2.核心安装方式3. MACOS 系统安