快速关闭所有打开的文件描述符
守护进程的实现过程中,有一个标准步骤就是关闭当前打开的所有文件描述符.APUE上给的做法是: int close_all_fd(void) { struct rlimit lim; unsigned int i; if (getrlimit(RLIMIT_NOFILE, &lim) < 0) return -1; if (lim.rlim_cur == RLIM_INFINITY) lim.rlim_cur = 1024; for (i = 0; i < lim.rlim_cur; i ) { #ifdef MYPERF if (i == 1) continue; #endif if (close(i) < 0 && errno != EBADF) return -1; } return 0; } 且不论当lim.rlim_curr为RLIM_INFINITY的时候,只关闭前1024个文件描述符是否充分,单单这个遍历所有可能打开的文件描述符就有些让人觉得不爽.值得庆幸的是现在的系统调用都很快,不然这么多系统调用谁知道会耗费多久时间啊.并且,通常情况下,守护进程启动的时候,打开的文件描述符就不多,为了少数几个描述符就如此大费周章不值当.故而我又转动我邪恶的小脑瓜,捣鼓出了以下奇技淫巧: int close_all_fd(void) { DIR *dir; struct dirent *entry, _entry; int retval, rewind, fd; dir = opendir("/dev/fd"); if (dir == NULL) return -1; rewind = 0; while (1) { retval = readdir_r(dir, &_entry, &entry); if (retval != 0) { errno = -retval; retval = -1; break; } if (entry == NULL) { if (!rewind) break; rewinddir(dir); rewind = 0; continue; } if (entry->d_name[0] == ''.'') continue; fd = atoi(entry->d_name); if (dirfd(dir) == fd) continue; #ifdef MYPERF if (fd == 1) continue; #endif retval = close(fd); if (retval != 0) break; rewind = 1; } closedir(dir); return retval; } 代码面前了无秘密,故不再费口舌解释.上测试程序: #define MYPERF int close_all_fd() { ... } int main(void) { struct timeval tv1, tv2, tv; gettimeofday(&tv1, NULL); close_all_fd(); gettimeofday(&tv2, NULL); timersub(&tv2, &tv1, &tv); printf("%ld.ld\n", tv.tv_sec, tv.tv_usec); return 0; } 测试结果: xiaosuo@gentux test $ ./apue.out 0.000147 xiaosuo@gentux test $ ./mine.out 0.000123 xiaosuo@gentux test $ ./apue.out 0.000150 xiaosuo@gentux test $ ./mine.out 0.000109 xiaosuo@gentux test $ ./apue.out 0.000156 xiaosuo@gentux test $ ./mine.out 0.000109 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |