发布于2020-01-05 16:58 阅读(1536) 评论(0) 点赞(22) 收藏(4)
os.listdir在内部执行什么系统调用,并且由于os.listdir
挂载的网络驱动器上的情况而导致Python进程挂起吗?
我们怀疑我们的应用服务器中存在问题,因为os.listdir
它试图列出安装在Linux机器上的samba共享。显然,在我们遇到此问题时,samba共享的DNS已经改变。我们仍在尝试复制这种情况,但是有人可以告诉我它如何工作吗?ls
像这样的命令也会挂吗?
有什么方法可以在用户空间处理?
CPython的实现os.listdir
使用特定于平台的C库调用来读取目录的内容。在类似Unix的平台上,它们是opendir(3)
and readdir(3)
,而在Windows上则使用FindFirstFile
and FindNextFile
。
在无法访问的网络文件系统的情况下,这些调用的行为将取决于操作系统。当使用Linux或Windows时,它们肯定会在系统命令(例如ls
hang)挂起的情况下挂起。为了防止任意长时间的停顿,可以使用专用框架,例如asyncio和twisted,它们使用非阻塞IO。但是,使用这些框架可能会让人望而生畏,并且通常需要在整个应用程序和整个程序中使用它们来构建事件驱动的模型。
确保存在网络文件系统时IO系统调用不会阻塞的一种更简单且对初学者友好的方法是使用线程。例如,这是一个safe_listdir
返回目录内容的函数,或者None
调用所花费的时间超过指定的超时时间:
import os, threading
def safe_listdir(directory, timeout):
contents = []
t = threading.Thread(target=lambda: contents.extend(os.listdir(directory)))
t.daemon = True # don't delay program's exit
t.start()
t.join(timeout)
if t.is_alive():
return None # timeout
return contents
在Python 3中,可以使用出色的concurrent.futures
软件包。它不仅简化了实现,而且还自动限制了多次safe_listdir
调用时创建的线程的数量,并确保将引发的异常os.listdir
正确传播到调用者:
import os, concurrent.futures
pool = concurrent.futures.ThreadPoolExecutor()
def safe_listdir(directory, timeout):
future = pool.submit(os.listdir, directory)
try:
return future.result(timeout)
except concurrent.futures.TimeoutError:
return None # timeout
作者:黑洞官方问答小能手
链接:https://www.pythonheidong.com/blog/article/205417/d551d6932f331e9ec337/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!