+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

os.listdir可以挂在网络驱动器上吗?它使用什么系统调用?

发布于2020-01-05 16:58     阅读(683)     评论(0)     点赞(22)     收藏(4)


0

1

2

3

4

5

6

7

8

9

os.listdir在内部执行什么系统调用,并且由于os.listdir挂载的网络驱动器上的情况而导致Python进程挂起吗?

我们怀疑我们的应用服务器中存在问题,因为os.listdir它试图列出安装在Linux机器上的samba共享。显然,在我们遇到此问题时,samba共享的DNS已经改变。我们仍在尝试复制这种情况,但是有人可以告诉我它如何工作吗?ls像这样的命令也会挂吗?

有什么方法可以在用户空间处理?


解决方案


CPython的实现os.listdir使用特定平台的C库调用来读取目录的内容。在类似Unix的平台上,它们是opendir(3)and readdir(3),而在Windows上则使用FindFirstFileand FindNextFile

在无法访问的网络文件系统的情况下,这些调用的行为将取决于操作系统。当使用Linux或Windows时,它们肯定会在系统命令(例如lshang)挂起的情况下挂起。为了防止任意长时间的停顿,可以使用专用框架,例如asynciotwisted,它们使用非阻塞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

0

1

2

3

4

5

6



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接: https://www.pythonheidong.com/blog/article/205417/d551d6932f331e9ec337/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

22 0
收藏该文
已收藏

评论内容:(最多支持255个字符)