iNotify 收到事件后如何关闭文件句柄

Posted

技术标签:

【中文标题】iNotify 收到事件后如何关闭文件句柄【英文标题】:How to close down file handles after iNotify receives an event 【发布时间】:2018-08-31 16:14:38 【问题描述】:

错误:

tail inotify 资源耗尽

我正在使用 Inotify 来监视目录中的任何文件更改。但问题是,这些文件很快就会耗尽 Inotifier 资源。它打开了数千个文件句柄。有没有办法在收到通知时立即关闭文件句柄?例如,如果在给定目录中创建了一个文件,我希望通知程序给我该文件的路径并关闭文件句柄,然后等待其他更改?

import inotify.adapters
import os
from config import DOCKER_PATH_TO_STREAMS

notifier = inotify.adapters.Inotify()
for files in os.listdir(DOCKER_PATH_TO_STREAMS):
    notifier.add_watch(os.path.join(DOCKER_PATH_TO_STREAMS,files))

def watch_for_files():
    for event in notifier.event_gen():
        if event is not None:
            if 'IN_CREATE' in event[1]:
                val = os.path.join(event[2],event[3])
                if val.endswith(".jpeg") or val.endswith(".jpg"):
                    return val

【问题讨论】:

什么是“Inotifier”?那是第三方工具、库还是你写的一些代码? Inotify * Inotify(inode notify)是一个 Linux 内核子系统,用于扩展文件系统以通知文件系统的更改,并将这些更改报告给应用程序。 您听起来很困惑——inotify(Linux 内核子系统)不会“打开数千个文件处理程序”。 Linux 内核不会自行打开文件句柄——用户空间代码会。问题是:您使用的是什么代码/工具?通知手表? inotifywait? @user1643723 我已经编辑了这个问题。我想我正在使用 inotifywatch 我正在将 ~100/秒的图像转储到我正在观看的目录中。 【参考方案1】:

嗯.... 我对您的问题和对他们的回答感到有些困惑。

当内核打开一个文件时,它会检查 inotify 队列,为它生成一条记录并将其排队。执行此操作的进程是发出open(2) 系统调用的进程,所以对我来说很奇怪,您可以很高兴每秒打开超过 100 个文件,而内核在某处丢失了信息。您遇到的问题(很可能,但我可能是错的)是 inotify 处理器没有时间获取如此多的打开事件并且队列已满。

这里有两种方法。第一个涉及扩展 inotify 队列以支持更多资源。我不知道 inotify 队列是否有一些运行时配置允许您执行此操作(无论如何您可以转到内核源并对此进行调整)第二个可能涉及 inotify 中的 bad design处理器...如果您的处理器处理 inotify 一次记录一个,并且假设您必须打开到远程站点的 tcp 连接以记录此类事件,那么您显然有麻烦了。由于您没有显示任何代码来识别可能会减慢 inotify 阅读器的速度,因此我无法为您提供一些解决方案,但问题就在那里:inotify 接收器不参加队列以处理 100 个事件/第二(或者比你在 cmets 中说的更多)

假设您打开一个队列以接收请求....但是您没有以允许它清空的速度阅读它。好吧,队列有一个上限,一旦达到上限,你就不能在队列中存储更多的东西......你必须做点什么。你知道我想去哪里吗?

【讨论】:

以上是关于iNotify 收到事件后如何关闭文件句柄的主要内容,如果未能解决你的问题,请参考以下文章

文件更改句柄,QSocketNotifier 由于无效套接字而禁用

Filebeat占用文件句柄

系统句柄数和进程句柄(max-file&ulimit -n)

关闭其它进程占用的文件句柄

python 文件读写操作

错误6句柄在Windows上写入文件无效[关闭]