inotify還是不錯的,玩著似乎很簡單,但是坑也不少,如果不仔細檢視官方文件,可能就真的不知道**存在坑,**需要注意。前段時間,在專案中使用inotify監控配置檔案,以達到實時感知配置改變的目的。但近日檢視線上日誌發現,配置檔案改變後,inotify並沒有通知,結果導致配置一直未被更改。
在描述之前,要說明一下,我**中的inotify使用方式,這個方式和網上大多方式一樣:
[cpp]view plain
copy
?#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倉庫...