Chinaunix首页 | 论坛 | 博客
  • 博客访问: 33884
  • 博文数量: 12
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 127
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-09 10:27
文章分类

全部博文(12)

文章存档

2014年(7)

2013年(5)

我的朋友

分类: LINUX

2014-05-03 22:59:48

转载自:
守护进程的实现过程中,有一个标准步骤就是关闭当前打开的所有文件描述符。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) |
给主人留下些什么吧!~~