inotify不生效問題

2021-07-15 12:45:40 字數 3768 閱讀 8679

inotify還是不錯的,玩著似乎很簡單,但是坑也不少,如果不仔細檢視官方文件,可能就真的不知道**存在坑,**需要注意。前段時間,在專案中使用inotify監控配置檔案,以達到實時感知配置改變的目的。但近日檢視線上日誌發現,配置檔案改變後,inotify並沒有通知,結果導致配置一直未被更改。

在描述之前,要說明一下,我**中的inotify使用方式,這個方式和網上大多方式一樣:

[cpp]view plain

copy

print

?#include 

#include 

#include 

static

const

char

kszconfigpath = 

"/usr/local/path/to/config"

;  static

ints_running = 0;  

extern

intreparse_config();  

intinotify_loop()  

/* watch config file. */

watch_fd = inotify_add_watch(inot_fd, kszconfigpath, watch_flag);  

if(watch_fd 

while

(s_running)  else

if(selret == 0) else

if(!fd_isset(inot_fd, &read_fds))   

read_cnt = read(fd, buffer, sizeof

(buffer));  

if(read_cnt <= 0)   

buffer_i = 0;  

while

(buffer_i 

buffer_i += sizeof

(struct

inotify_event) + pevent->len;  

}  }  

/** remove watch. */

if(inotify_rm_watch(inot_fd, watch_fd) 

return

0;  

}  

一、使用vi編輯a檔案,然後儲存。程式沒有截獲in_modify事件,列印的是unrecongnized event mask 32768。

二、使用mv更改檔案,也就是使用命令mv a a.bak。在mv後,發現程式沒能截獲in_modify事件,列印的是unrecongnized event mask 32768。

三、刪除a檔案,並重啟程式,發現inotify_init註冊失敗,而errno為2。

看來,我的程式是有問題的。那麼32768到底是什麼呢?檢視官方的inotify文件

,發現32768是in_ignored,表示使用者對watch識別符號呼叫了inotify_rm_watch,或者watch識別符號被自動從inotify中移除。意思很明顯,就是檔案被刪除了。inotify只是監視控制代碼,並非檔案路徑,當檔案標示符對應的檔案被刪除時,這個檔案識別符號也被自動從inotify中移除,在以上的**中,也就意味著inotify中沒有任何watch識別符號了,自然也就不會通知in_modify事件。

等等,在第乙個步驟中,我們不是修改了a檔案嗎?那至少應該打出in_modify吧。這裡要解釋一下,vi編輯時會先將檔案儲存為a.swap,等編輯完畢後再移動回來或者刪除,具體移動回來還是刪除,取決於是退出vi時是儲存操作,還是取消操作。所以這裡根本沒有觸發in_modify事件,實際上觸發的是in_move_to事件(a檔案被移出),以及in_ignored事件等等。

這裡要注意的是:檔案被刪除,不一定會產生in_ignored事件,也就是說檔案被刪除時,不一定會把檔案對應的識別符號自動從inotify中刪除。在這些情況下,我們需要重新對檔案重新

註冊監控。

在第三個測試中,我們看到inotify只會對存在的檔案進行監控,如果要實現無**件是否存在都持續監控,那麼我們需要自動重新註冊監控。

以下是修改後的**:

[cpp]view plain

copy

print?

#include 

#include 

#include 

static

const

char

kszconfigpath = 

"/usr/local/path/to/config"

;  static

ints_running = 0;  

extern

intreparse_config();  

#ifdef _win32

struct

inotify_event ;  

intinotify_init(

void

);  

intinotify_add_watch(

intfd, 

const

char

*pathname, uint32_t mask);  

intinotify_rm_watch(

intfd, 

intwd);  

#endif

intset_non_blocking(fd)  

intrm_inotify_wd(

intfd, 

intwd)  

return

inotify_rm_watch(fd, wd);   

}  int

inotify_loop()  

if(set_non_blocking(inot_fd) 

while

(s_running)  else

}  seltime.tv_sec = 1;  

seltime.tv_usec = 0;  

if(watch_fd 

if(selret 

if(selret == 0)  else

if(!fd_isset(inot_fd, &read_fds))   

read_cnt = read(fd, buffer, sizeof

(buffer));  

if(read_cnt <= 0)   

need_parse = 0;  

need_remove_wd = 0;  

buffer_i = 0;  

while

(buffer_i 

if(pevent->mask & in_close_write)  else

if(pevent->mask & in_create)  else

if(pevent->mask & (in_delete | in_delete_self))  else

if(pevent->mask & (in_move | in_move_self))  else

buffer_i += sizeof

(struct

inotify_event) + pevent->len;  

}  if

(need_parse)   

if(need_remove_wd)   

watch_fd = -1;  

}  }  

/** remove watch. */

if(inotify_rm_watch(inot_fd, watch_fd) 

close(inot_fd);  

return

0;  

}  

gitignore 不生效問題

在git中如果想忽略掉某個檔案,不讓這個檔案提交到版本庫中,可以使用修改根目錄中 gitignore 檔案的方法 如無,則需自己手工建立此檔案 這個檔案每一行儲存了乙個匹配的規則例如 1 2 3 4 5 6 7 此為注釋 將被 git 忽略 a 忽略所有 a 結尾的檔案 lib.a 但 lib.a ...

setLayoutParams 不生效問題

1.使用此方法時必須是使用該控制項的父布局 類似於這樣乙個布局,如果要對裡面的imageview進行此項操作就應該是這樣 linearlayout layoutparams params new linearlayout layoutparams iv.getlayoutparams 然後設定你想改...

gitignore不生效問題

在使用git進行版本控制的過程中發現,將想被忽略的檔案 資料夾 配置到.gitignore檔案中後,實際修改了想被忽略的檔案,呼叫git status檢視時,仍然會提示提交這些檔案。也就是說實際並沒有被忽略 原因是git ignore只會對不在git倉庫中的檔案進行忽略,如果這些檔案已經在git倉庫...