转载自:
守护进程的实现过程中,有一个标准步骤就是关闭当前打开的所有文件描述符。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.%06ld\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
阅读(800) | 评论(0) | 转发(0) |