inotify/stat是否存在竞争条件?Linux下C进程异常问题咨询
Absolutely—this is exactly the kind of edge-case race condition that pops up with inotify, and it directly explains the behavior you’re seeing. Here’s a breakdown of what’s happening:
The Problematic Execution Timeline
For this issue to trigger, process scheduling has to align perfectly (or perfectly badly):
- Process B calls
inotify_add_watch(inotify_fd, "/watch", IN_CREATE);and enters the kernel’s handling logic. But the kernel hasn’t finished attaching the watch to the/watchdirectory’s metadata yet—think of it as the watch is "half-setup" and not yet active. - Process A gets scheduled in right at this window, runs
open("/watch/item", O_CREAT, 0); close(fd);, and successfully creates the file. Since the watch on/watchisn’t fully active yet, the kernel doesn’t generate anIN_CREATEevent for it. - Process B resumes execution, and the kernel finishes setting up the inotify watch—now it’s active and ready to catch future events.
- Process B runs
stat("/watch/item");and gets-1(meaning the file no longer exists—this could happen if another process deleted it, or in an even rarer edge case, the file creation was rolled back for filesystem-specific reasons). - When Process B polls for inotify events, it finds nothing: the
IN_CREATEevent never got generated because the watch wasn’t active when the file was created.
Why This Happens
Inotify is designed to only capture events that happen after the watch is fully established. The inotify_add_watch() call isn’t atomic from the perspective of other processes—there’s a tiny window where the kernel is still wiring up the watch, and any filesystem operations on the target directory during that window won’t trigger events.
How to Fix It
To avoid missing events in this scenario, you have a few practical options:
- Stat first, watch second: Have Process B run
stat("/watch/item");before callinginotify_add_watch(). If the file exists, handle it immediately; if not, then set up the watch. This covers the case where the file was created right before the watch went live. - Combine polling with inotify: Keep a periodic poll of the
/watchdirectory alongside your inotify event handling. This acts as a safety net for edge cases where events slip through the cracks. - Use inter-process synchronization: If you control both processes, add a sync primitive (like a mutex or semaphore) to ensure Process B finishes setting up the watch before Process A creates the file. This eliminates the race window entirely, but only works if you can modify both processes’ code.
内容的提问来源于stack exchange,提问作者Shuangistan

