Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2033967
  • 博文数量: 369
  • 博客积分: 10093
  • 博客等级: 上将
  • 技术积分: 4271
  • 用 户 组: 普通用户
  • 注册时间: 2005-03-21 00:59
文章分类

全部博文(369)

文章存档

2013年(1)

2011年(2)

2010年(10)

2009年(16)

2008年(33)

2007年(146)

2006年(160)

2005年(1)

分类: LINUX

2010-06-29 13:15:48

闲得蛋疼,想去统计一下FreeBSD和Linux内核代码行数,好“羞辱”一下FreeBSD,并籍此慰藉一下自己作为Linux用户的虚荣之心(就是鲁迅笔下的阿Q精神):

xiaosuo@gentux FreeBSD $ svn up
版本 209583。
xiaosuo@gentux FreeBSD $ find . -name "*.[hc]" | xargs wc -l
...
  836324 总用量
...
localhost linux # git pull
Already up-to-date.
localhost linux # find . -name "*.[hc]" | xargs wc -l
 19537 total

结果让我愕然,太假了吧,FreeBSD竟然比Linux代码量大,并且Linux才那么点儿代码?应该是统计方法有问题,换用perl语言实现一个统计程序如下:

#!/usr/bin/perl -w
#

$line = 0;


open($files, 'find . -name "*.[hc]" |');
while (<$files>) {
        open($fp, $_);
        while (<$fp>) {
                $line++;
        }
}

print $line . "\n";


运行之:

xiaosuo@gentux FreeBSD $ ./line.pl
3956986
...
localhost linux # ./line.pl
11898857

长出一口气,终于得到了靠谱的数据,并且虚荣心得到些许满足,Linux代码行数是FreeBSD的3倍多。

那么,先前的统计为什么出错了呢?以前我可都是这么统计代码行数的。猜测是因为文件数量太多,xargs不能一次性将所有文件的路径以参数的形式传递给wc,致使wc被调用了多次。检测方法比较简单,在原有的命令基础上再加一个过滤器,筛选出总用量统计。

xiaosuo@gentux FreeBSD $ find . -name "*.[hc]" | xargs wc -l | grep 总用量
 3120662 总用量
  836324 总用量

和结论相符,那么修正一下shell脚本,让xargs每次传给wc一个参数,并用其他方式统计行数。

xiaosuo@gentux FreeBSD $ find . -name "*.[hc]" | xargs -L 1 wc -l | awk '{print $1}' | while read num; do total=$((total+num)); echo $total; done
...
3956986

这次得出了正确的数字,只是速度较慢,其实可以将统计方法应用于上一个过滤后的结果以加速执行。

那么xargs传递的参数个数的上限是多少呢?统计了一下每次wc调用的参数个数:

localhost linux # find . -name "*.[hc]" | xargs ./a.pl
4708
3460
3730
3998
4110
3544
4157
1798

并没有发现任何规律。看来还得翻源码:


/* IEEE Std 1003.1, 2003 specifies that the combined argument and
       * environment list shall not exceed {ARG_MAX}-2048 bytes. It also
       * specifies that it shall be at least LINE_MAX.
       */

#ifdef _SC_ARG_MAX
      long val = sysconf(_SC_ARG_MAX);
      if (val > 0)
        {
          /* Note that val can in fact be greater than ARG_MAX
           * and bc_ctl.arg_max can also be greater than ARG_MAX.
           */

          assert (bc_ctl.arg_max <= (val-XARGS_POSIX_HEADROOM));
        }
      else
        {
# if defined ARG_MAX
          assert (bc_ctl.arg_max <= (ARG_MAX-XARGS_POSIX_HEADROOM));
# endif
        }
#else
      /* No _SC_ARG_MAX */
      assert (bc_ctl.arg_max <= (ARG_MAX-XARGS_POSIX_HEADROOM));
#endif


可见有相关的sysconf变量,但是你查看其相应的man page字段,发现这个数值其实不怎么可靠。

       ARG_MAX - _SC_ARG_MAX
              The  maximum  length  of  the arguments to the exec(3) family of
              functions.  Must not be less than _POSIX_ARG_MAX (4096).

BUGS
       It  is difficult to use ARG_MAX because it is not specified how much of
       the argument space for exec(3) is consumed by  the  user's  environment
       variables.

       Some  returned values may be huge; they are not suitable for allocating
       memory.

比较保险的做法还是尽量避免过多参数吧。
阅读(7773) | 评论(1) | 转发(0) |
0

上一篇:2^6

下一篇:对BSD的一点理解:防火墙和QoS

给主人留下些什么吧!~~

GFree_Wind2011-05-12 22:00:51

以前遇到过参数过多结果导致了意想不到的问题。。。。大概问题好像是代码中查找要需要的参数,然后传递给命令。结果参数过多,直接导致命令失败。。