# Get the procs sorted by the number of inotify watchers # # From `man find`: # %h Leading directories of file's name (all but the last element). If the file name contains no slashes (since it # is in the current directory) the %h specifier expands to `.'. # %f File's name with any leading directories removed (only the last element). lines=$( find /proc/*/fd \ -lname anon_inode:inotify \ -printf '%hinfo/%f\n' 2>/dev/null \ \ | xargs grep -c '^inotify' \ | sort -n -t: -k2 -r \ )
printf "\n%10s\n" "INOTIFY" printf "%10s\n" "WATCHER" printf "%10s %5s %s\n" " COUNT " "PID" "CMD" printf -- "----------------------------------------\n" for line in $lines; do watcher_count=$(echo $line | sed -e 's/.*://') pid=$(echo $line | sed -e 's/\/proc\/\([0-9]*\)\/.*/\1/') cmdline=$(ps --columns 120 -o command -h -p $pid) printf "%8d %7d %s\n" "$watcher_count" "$pid" "$cmdline" done
nfds should be set to the highest-numbered file descriptor in any of the three sets, plus 1. The indicated file descriptors in each set are checked, up to this limit (but see BUGS).
Three independent sets of file descriptors are watched.
The file descriptors listed in readfds will be watched to see if characters become available for reading (more precisely, to see if a read will not block; in particular, a file descriptor is also ready on end-of-file).
The file descriptors in writefds will be watched to see if space is available for write (though a large write may still block).
The file descriptors in exceptfds will be watched for exceptional conditions. (For examples of some exceptional conditions, see the discussion of POLLPRI in poll(2).)
The time structures involved are defined in <sys/time.h> and look like
1 2 3 4
structtimeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ };
and
1 2 3 4
structtimespec { long tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
intpoll(struct pollfd *fds, nfds_t nfds, int timeout);
structpollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ };
采用数组指针+长度的参数形式
返回值
1 2 3 4 5
On success, a positive number is returned; this is the number of structures which have nonzero revents fields (in other words, those descriptors with events or errors reported). A value of 0 indicates that the call timed out and no file descriptors were ready. On error, -1 is returned, and errno is set appropriately.
水平触发
其和select不同的地方:采用数组的方式替换原有fd_set数据结构,而使其没有连接数的限制。
虽然也是轮询,但是假设是单个fd,但fd的值很大的情况下,poll就会比select效率好
上面看到了只需要一次初始化,和恢复已经就绪的fd,不需要每次初始化
可移植性:select( ) is more portable, as some Unix systems do not support poll( )
epoll
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
intepoll_create(int size); // Since Linux 2.6.8, the size argument is ignored, but must be greater than zero; intepoll_ctl(int epfd, int op, int fd, struct epoll_event *event); intepoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);
functioncancelTimer(id) { if (useRAF) { return root.cancelAnimationFrame(id) } clearTimeout(id) }
functionleadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time // Start the timer for the trailing edge. timerId = startTimer(timerExpired, wait) // Invoke the leading edge. return leading ? invokeFunc(time) : result }
functionremainingWait(time) { const timeSinceLastCall = time - lastCallTime const timeSinceLastInvoke = time - lastInvokeTime const timeWaiting = wait - timeSinceLastCall
functionshouldInvoke(time) { const timeSinceLastCall = time - lastCallTime const timeSinceLastInvoke = time - lastInvokeTime
// Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)) }
functiontimerExpired() { const time = Date.now() if (shouldInvoke(time)) { returntrailingEdge(time) } // Restart the timer. timerId = startTimer(timerExpired, remainingWait(time)) }
functiontrailingEdge(time) { timerId = undefined
// Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { returninvokeFunc(time) } lastArgs = lastThis = undefined return result }