linux inotify 研究8

找inotify_init对应的函数。一直认为是inotify_destroy。貌似不对。

其实inotify_init打开了一个文件,用read可以操作,那么关闭应该使用close才对。

一直看有介绍要配合select使用,现在还没用上,不知道怎么用。

http://www.ibm.com/developerworks/cn/linux/l-ubuntu-inotify/index.html

notify 是一个 Linux 内核特性,它监控文件系统,并且及时向专门的应用程序发出相关的事件警告,比如删除、读、写和卸载操作等。您还可以跟踪活动的源头和目标等细节。

使用 inotify 很简单:创建一个文件描述符,附加一个或多个监视器(一个监视器 是一个路径和一组事件),然后使用 read() 方法从描述符获取事件信息。read() 并不会用光整个周期,它在事件发生之前是被阻塞的。

更好的是,因为 inotify 通过传统的文件描述符工作,您可以利用传统的 select() 系统调用来被动地监控监视器和许多其他输入源。两种方法 — 阻塞文件描述符和使用 select()— 都避免了繁忙轮询。

现在,让我们深入了解 inotify,写一些 C 代码,然后看看一组命令行工具,您可以构建并使用它们将命令和脚本附加到文件系统事件。Inotify 不会在中途失去控制,但它可以运行 cat 和 wget,并且在必要时严格执行。


Inotify 提供 3 个系统调用,它们可以构建各种各样的文件系统监控器:

  • inotify_init() 在内核中创建 inotify 子系统的一个实例,成功的话将返回一个文件描述符,失败则返回 -1。就像其他系统调用一样,如果 inotify_init() 失败,请检查 errno 以获得诊断信息。
  • 顾名思义,inotify_add_watch() 用于添加监视器。每个监视器必须提供一个路径名和相关事件的列表(每个事件由一个常量指定,比如 IN_MODIFY)。要监控多个事件,只需在事件之间使用逻辑操作符或 — C 语言中的管道线(|)操作符。如果inotify_add_watch() 成功,该调用会为已注册的监视器返回一个惟一的标识符;否则,返回 -1。使用这个标识符更改或删除相关的监视器。
  • inotify_rm_watch() 删除一个监视器。

此外,还需要 read() 和 close() 系统调用。如果描述符由 inotify_init() 生成,则调用 read() 等待警告。假设有一个典型的文件描述符,应用程序将阻塞对事件的接收,这些事件在流中表现为数据。文件描述符上的由 inotify_init() 生成的通用 close() 删除所有活动监视器,并释放与 inotify 实例相关联的所有内存(这里也用到典型的引用计数警告。与实例相关联的所有文件描述符必须在监视器和 inotify 消耗的内存被释放之前关闭)。

这个强大的工具提供 3 个应用程序编程接口(API)调用,以及简单、熟悉的范例 “所有内容都是文件”。

使用 inotify 的技巧

您还可以使用 select()pselect()poll() 和 epoll() 来避免阻塞。如果您想将监视器的监控作为图形应用程序的主事件处理循环的一部分,或作为监视其他输入连接的守护进程的一部分,这是很有用的。将该 inotify 描述符添加到这组描述符中,进行并发监控。清单 5 展示了 select() 的标准形式。


清单 5. select() 的标准形式
int return_value;
fd_set descriptors;
struct timeval time_to_wait;

FD_ZERO ( &descriptors );
FD_SET( ..., &descriptors );
FD_SET ( fd, &descriptors );

...

time_to_wait.tv_sec = 3;
time.to_waittv_usec = 0;

return_value = select ( fd + 1, &descriptors, NULL, NULL, &time_to_wait);

if ( return_value < 0 ) {
	/* Error */
}

else if ( ! return_value ) {
	/* Timeout */
}

else if ( FD_ISSET ( fd, &descriptors ) ) {
	/* Process the inotify events */
	...
}

else if ...

select() 方法在 time_to_wait 期间暂停程序。然而,如果在这个延迟期间这组描述符的任意一个文件描述符发生活动,将立即恢复执行程序。否则,调用就会超时,允许应用程序执行其他进程,比如在图形用户界面(GUI)工具中响应鼠标或键盘事件。

下面是使用 inotify 的其他技巧:

  • 如果监视中的文件或目录被删除,它的监视器也会被自动删除(在删除事件发出之后)。
  • 如果在已卸载的文件系统上监控文件或目录,监视器将在删除所有受影响的监视之前收到一个卸载事件。
  • 将 IN_ONESHOT 标志添加到监视器标记中,设置一个一次性警告。警告在发送之后将被删除。
  • 要修改一个事件,必须提供相同的路径名和不同的标记。新监视器将取代老监视器。
  • 考虑到实用性,不可能耗尽任何一个 inotify 实例的监视器。然而,您可能会耗尽事件队列的空间,这取决于处理事件的频率。队列溢出会引起 IN_Q_OVERFLOW 事件。
  • close() 方法毁坏 inotify 实例和所有相关联的监视器,并清空队列中的所有等待事件。


你可能感兴趣的:(linux,inotify,linux)