[阅读笔记]fsnotify源码阅读

news/2024/7/5 20:32:01
fsnotify的github地址是
https://github.com/howeyc/fsnotify

fsnotify是一个文件夹监控应用。可以使用创建一个watcher来对某个文件夹进行监控


文件目录很简单,实际就两个程序文件,fsnotify.go 和 各平台的fsnotify_XXX.go
后一个文件是各个不同平台的实现

example_test.go中给的是最简单的实际应用
先fsnotify.NewWatcher()
再开一个goroutine监听文件夹修改的事件
然后使用watcher.Watch()来监听一个文件夹

fsnotify中的几个public函数Watch,WatchFlags,RemoveWatch是对Watcher的具体封装,函数名一看就明白了什么意思。
这里的flag标志watcher要监听文件夹的哪些事件,Watch默认监听所有事件。

String函数能用string表示出事件。这里学了一招使用events = events[1:] 来达到trim同样的目的。

purgeEvents是将内部事件转成外部事件。这个内部事件指的是syscall包有的对事件的封装和标志位,外部事件指fsnotify对事件的再次封装

下面就到fsnotify_linux.go看linux平台下的实现。
FileEvent类型:
mask,代表事件的掩码,这里的事件码对应的实际上是syscall包中constants对应的一些位置码
cookie,每个事件会分配一个唯一的cookie,这个具体是什么也不理解
Name,触发事件的文件名


下面是一个watch类型
wd,syscall中对文件监控返回的watch id
flags,syscall中对文件的flag

watcher结构:
mu:互斥锁,控制并发,对watcher要进行互斥监控
fd:watcher的文件描述符,不要把这个理解成监控的文件的文件描述符。理解成通知watch消息的文件描述符
watches:要监控的文件夹路径和watch结构的映射
fsnFlags:要监控的事件标志位
paths:要监控watch id和文件夹路径的映射,上面三个其实和起来就能完成了path和watch的互相查找
Error:如果发生错误,从这个channel将错误通知主go routine
internalEvent:文件事件队列,内部的文件事件就放在这个队列中
Event:已经处理的文件事件队列
done:主goroutine监听是否已经结束的通知通道
isClose:是否已经结束的标志位,当然只能自身的goroutine使用

下面看NewWatcher这个函数
这里调用了syscall的InotifyInit来进行初始化
学了一点,当syscall出现错误的时候,可以使用os.NewSyscallError来抛出错误
里面起了两个goroutine
readEvents()和purgeEvents()

purgeEvents()上面已经有了,下面是readEvents
先从w.fd中获取出syscall.InotifyEvent,这个是syscall包的通知事件。这个事件是怎么被塞入这个fd的呢?是syscall的syscall.InotifyAddWatch之后如果文件有修改就会将event写入到这个fd中。这个fd就相当于是一个先进先出的队列了。

读出InitofifyEvent之后就需要将它变成我们这个包中定义的fileEvent。并将这个event放入到internalEvent中去。这里只是捕获消息,并没有对消息进行过滤之类的操作。考虑是否弹出和是否返回是在purgeEvent中进行过滤。

对readEvents读完之后其他的就很好理解了。
addWatch就是调用了一下syscall.InotifyAddWatch
removeWatch就是调用了一下syscall.InotifyRmWatch 




本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2012/12/02/2798505.html,如需转载请自行联系原作者

http://www.niftyadmin.cn/n/595135.html

相关文章

CentOS7下python3+Flask+uWSGI+Nginx+Supervisor环境搭建

在生产环境中通常用uwsgi作为Flask的web服务网关,通过nginx反向代理进行负载均衡,通过supervior进行服务进行的管理。这一套搭下来还是有一些坑要踩,本文通过一个简单的Flask web应用记录了CentOS7下python3FlaskuWSGINginxSupervisor环境搭建…

JS框架刷新,iframe父子窗口间js方法调用

Response.Write("<script languagejavascript>window.open(x.aspx,main);</script>"); Javascript刷新页面的几种方法&#xff1a;1 history.go(0) 2 location.reload() 3 locationlocation 4 location.assign(location) 5 document.ex…

nicegram安卓_Nicegramapp

《Nicegramapp》这款谈天软件的功用十分的完全&#xff0c;不管小伙伴是想要找到你之间的谈天记载仍是想要保存记载的话&#xff0c;都能够只需要悄悄一点就能够完成了&#xff01;一同还可认为你主动过滤一些废物信息&#xff0c;让你享用到一个更夸姣的谈天环境&#xff01;N…

mysql运行sql错误1055_sql数据库执行错误代码1055怎么解决?

展开全部 错误代码1055。不过看了Expression里面的原因描述,我基本知道怎么回事了。原因是因为62616964757a686964616fe59b9ee7ad9431333431373139mysql中对 group by 用法的规定。严格意义上说,就是group by之后。select 的字段只能是group by的字段。或者需要加聚合函数的。…

非常非常容易理解和简明的CPU漏洞说明

为什么80%的码农都做不了架构师&#xff1f;>>> 非常非常容易理解和简明的CPU漏洞说明&#xff1a; 1.kfc里卖的有薯条、鸡块、汉堡、可乐。 2.李小璐去kfc点了个汉堡&#xff0c;吃完走了。 3.狗仔队a狗仔排在李小璐后面的后面&#xff0c;和点餐小姐姐说&#xf…

Python通过GeoIP获取IP信息(国家、城市、经纬度等)

IP地址信息是非常重要的情报信息&#xff0c;通过IP可以定位到该IP所在的国家、城市、经纬度等。 获取IP信息的方式有很多&#xff0c;很多服务商都提供了相应的地址库或API接口服务。 如国内的ipip.net&#xff0c;国外的ip-api.com、maxmind.com等。 很多公司都是使用Maxmind…

c++ 读取内存数据 基址_什么是物理地址?不知道没关系,今天程序员带你认识各种内存地址...

物理地址就是内存单元的绝对地址&#xff0c;物理地址0x0000就表示内存条的第一个存储单元&#xff0c;0x0010(16进制)就表示内存条的第17个存储单元&#xff0c;一个存储单元是1byte(8bit)。你问为什么是1byte&#xff1f;一个内存条是由若干个黑色的内存颗粒构成的。每一个内…

JS 将框架子窗口中的内容存放到父页面的div中

//index.htm<html><head><meta http-equiv"Content-Type" content"text/html; charsetgb2312"><title>新建网页 1</title><script language"javascript">function getFrameBody(){ //将框架子窗口中的内…