os.system() 即使在互斥锁下也会导致 print() python 函数的控制台输出无效
Posted
技术标签:
【中文标题】os.system() 即使在互斥锁下也会导致 print() python 函数的控制台输出无效【英文标题】:os.system() leads to invalid console output of print() python function even under mutex 【发布时间】:2021-09-17 07:25:27 【问题描述】:我制作了一个脚本,它通过 ThreadPool 中的os.system()
调用一些程序并将工作结果打印到控制台。简化后的代码是这样的:
import os
from concurrent.futures import ThreadPoolExecutor, as_completed
import multiprocessing
from threading import Lock
print_mutex = Lock()
def print_safe(text):
with print_mutex:
print(text, flush=True)
def print_smth():
res = os.system("")
print_safe("1")
with ThreadPoolExecutor(max_workers = multiprocessing.cpu_count()) as thread_pool:
future_results = [thread_pool.submit(print_smth) for i in range(40)]
for future in future_results:
future.result()
但是在控制台输出中我收到了这样的意外结果:
如果我评论res = os.system("")
call,则输出有效。
为什么 os.system() 会以这种方式影响打印功能?
实施流程调用以避免此类问题的正确方法是什么?
【问题讨论】:
你是真实的(非简化的)子进程打印的东西吗? 我无法使用os.system("")
重现此内容。
我确实可以在 Windows 上重现
@o11c 没关系。我在简化示例中尝试了这两个选项并得到了相同的行为。我在 cmd 中在 Windows 10 上的 python 3.8.2 上运行了示例
即使在os.system("")
的情况下,该问题也是可重现的,因此没有输出。
【参考方案1】:
发生了什么:
Threadpool 创建一个并行工作的线程池。但是,您的主线程仍然是单线程。如果您的作业不需要时间(小于循环调用函数本身的周期),它将在调用下一个函数所需的时间内完成,它将显示为同步的。
os.system
在你的电脑上花费了一些时间(这可能会根据速度、操作系统和 CPU 数量而变化),因此线程同时结束,并且由于调用 os.system
的工作延迟,它们正在彼此相邻打印,因为它们在主应用程序的同一个单线程循环中打印(打印到控制台的那个)。
如果您的函数确实有效,您会看到预期的结果。
【讨论】:
所以你建议一些解决方法来隐藏问题? 我的建议是它应该正常工作。您不应该依赖 print 函数来测试异步。相反,您应该依赖完整的操作时间。以上是关于os.system() 即使在互斥锁下也会导致 print() python 函数的控制台输出无效的主要内容,如果未能解决你的问题,请参考以下文章
为什么用cycle()创建的迭代器中的可变值没有更新,即使有停止条件,也会导致无限循环?
即使在 C# 代码中处理,InvalidOperationException 也会导致 Visual Studio 中断
在 os.system() 期间,啥会导致“IOError: [Errno 9] Bad file descriptor”?