文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>快速关闭所有打开的文件描述符

快速关闭所有打开的文件描述符

时间:2010-08-12  来源:xiaosuo

守护进程的实现过程中,有一个标准步骤就是关闭当前打开的所有文件描述符。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

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载