/dev/null 的原理是什么?大量写入会影响系统性能吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
yjsslab
V2EX    Linux

/dev/null 的原理是什么?大量写入会影响系统性能吗?

  •  
  •   yjsslab 201504-13 20:41:56 +08:00 9651 次点击
    这是一个创建于 3841 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 1 条附言    2015-04-14 09:14:02 +08:00
    找到一个解释:https://bbs.archlinux.org/viewtopic.php?id=137861

    It's all implemented via file_operations (drivers/char/mem.c if you're curious to look yourself):

    ```
    static const struct file_operations null_fops = {
    .llseek = null_lseek,
    .read = read_null,
    .write = write_null,
    .splice_write = splice_write_null,
    };
    ```

    write_null is what's called when you write to /dev/null. It always returns the same number of bytes
    that you write to it:

    ```
    static ssize_t write_null(struct file *file, const char __user *buf,
    size_t count, loff_t *ppos)
    {
    return count;
    }
    ```

    That's it. The buffer is just ignored.


    写时竟然还 return 一个 size !
    29 条回复    2015-04-15 10:02:14 +08:00
    bellchu
        1
    bellchu  
       2015-04-13 21:30:44 +08:00   9
    /dev/null类似一个黑洞,写入任何东西都会返回成功,但是实际写入数据随即被丢弃。

    /dev/null的io只是软件层面的,实际没有存储的io动作。但是既然是软件层面的,就会有userspace到kernel的system call,会耗费相当多的CPU和内存。

    因为传入/dev/null的数据几乎是在其被从软件传出的同时被丢弃的,所以传输的速度基本没有延迟,CPU占用率基本会迅速被占满。
    bellchu
        2
    bellchu  
       2015-04-13 21:34:46 +08:00   3
    rming
        3
    rming  
       2015-04-13 21:44:14 +08:00   1
    好像,貌似,记得,有人说过这个问题,在 C 的实现中,是直接使用的 return
    julyclyde
        4
    julyclyde  
       2015-04-13 21:52:33 +08:00   1
    @rming 这个不存在所谓在C的实现中的说法。虽说内核都是C写的,但这事和语言没关系
    tabris17
        5
    tabris17  
       2015-04-13 22:10:09 +08:00
    会有系统调用,所以开销也不算小
    rming
        6
    rming  
       2015-04-13 22:11:26 +08:00
    @bellchu 说的很对
    rrfeng
        7
    rrfeng  
       2015-04-13 22:18:21 +08:00   1
    @bellchu

    这个实验说明了 yes 能使 CPU 使用率增加到 100%。
    ryd994
        8
    ryd994  
       2015-04-13 22:36:46 +08:00
    @bellchu 这只是yes本身的开销而已吧……
    不能认为是/dev/null的
    tianice
        9
    tianice  
       2015-04-13 23:13:05 +08:00
    loading
        10
    loading  
       2015-04-13 23:13:53 +08:00 via Android
    不是你写到哪,写这个动作就耗资源,只是io部分少很多。
    bellchu
        11
    bellchu  
       2015-04-14 06:34:02 +08:00
    @ryd994 对哦,那换一个往null写0的,更贴切点
    cat /dev/zero > /dev/null
    bellchu
        12
    bellchu  
       2015-04-14 06:55:11 +08:00
    @rrfeng 这个实验也说明了频繁写入/dev/null同样会消耗资源影响性能,而不会像很多人想象的输出到null的就不耗费任何资源,但实际上CPU的开销是一样的。

    如果纠结yes命令的话。就换cat /dev/zero > /dev/null,其实效果是一样的,只不过一个是不断输出y,一个是不断输出0.

    我的本意只想表达:把/dev/null当成一个0延迟的IO设备,当IO没有延迟的时候,CPU会成为最大的系统瓶颈,CPU会因为无法及时处理排队的数据而满负载。
    ryd994
        13
    ryd994  
       2015-04-14 07:48:51 +08:00 via Android   1
    @bellchu 那就变成cat的开销了……
    不过到null没开销这个肯定不可能,系统调用是少不了的。不过有多大开销就很难说了,如果只是百分之一/千分之一,认为可以忽略也没什么。
    bellchu
        14
    bellchu  
       2015-04-14 08:44:10 +08:00 via iPhone
    @ryd994 楼主和我说的都是写入null造成的开销,不能单纯说是一个进程的开销或者是null的开销

    这类似于讨论网络 A发送包给B 当A到B的延迟很高时会不会性能下降 当A到B基本无延迟时会不会有性能下降。还有性能下降的程度和速度。当量达到一定程度的时候,例如A有无数个副本同时发送数据给B的时候,一定量时B就瘫痪了,ddos成功。

    就像你所说百分之一千分之一的开销基本可忽略,所以很多人喜欢把null当成焚化炉,把垃圾输出全丢null,不占用存储,不消耗io。现代系统的大多数应用的性能瓶颈都是io。

    歪楼了...
    bellchu
        15
    bellchu  
       2015-04-14 09:06:43 +08:00 via iPhone
    @ryd994 或者换句话说,百分之一千分之一的量不能算是大量。大数据时代要机器所产生的数据很简单就能“大量”。

    可以参照keen.io
    ryd994
        16
    ryd994  
       2015-04-14 09:15:41 +08:00 via Android
    @bellchu 即使是yes这样的程序,生成这么多数据的开销也比null丢弃这么多的大。那么忽略null的开销就是合理的。
    这时候需要检讨的不是为什么输出到null,而是为什么平白无故生成这么多无用的数据。这么多数据,无论输出到哪里都是浪费。
    这就像listen lo和用socket的区别。用loopback固然比用sock开销大,不过实际上可以忽略。倒不如考虑一下怎么减少不必要的进程间数据交换。
    yjsslab
        17
    yjsslab  
    OP
       2015-04-14 09:17:08 +08:00
    所以,没有实际的 IO 发生,只是 return count 的开销。
    yjsslab
        18
    yjsslab  
    OP
       2015-04-14 09:18:21 +08:00
    谢谢楼上各位。
    wizardoz
        19
    wizardoz  
       2015-04-14 09:29:15 +08:00
    要是写的时候不返回size的话,应用程序岂不是认为没有写进去进而重复写同一个内容?
    bellchu
        20
    bellchu  
       2015-04-14 09:32:08 +08:00
    @ryd994 你说的都对,但是你没考虑到垃圾达到一定程度的时候的问题。

    http://devnull-as-a-service.com/
    Admstor
        21
    Admstor  
       2015-04-14 09:37:56 +08:00
    我有时候会把暂时不需要的日志指向null,需要的时候再指向别的地方...
    bellchu
        22
    bellchu  
       2015-04-14 10:03:41 +08:00
    bellchu
        23
    bellchu  
       2015-04-14 10:18:25 +08:00
    @wizardoz 有返回的,输出多少就返回多少
    static ssize_t write_null(struct file *file, const char __user *buf,
    size_t count, loff_t *ppos)
    {
    return count;
    }
    fxxkgw
        24
    fxxkgw  
       2015-04-14 16:15:02 +08:00
    这个一般都是在脚本里面用的吧,特别是一些crontab定时器中执行的脚本,大部分作用是把无用或出错信息不显示。
    如果考虑到使用的情况,将打印显示到界面的资源消耗量应远大于输入到/dev/null 所以个人感觉可以放心使用。
    vonnyfly
        25
    vonnyfly  
       2015-04-14 16:54:47 +08:00   1
    这个return size一定要,不要的话,用户态write会返回失败。以前写驱动的时候这里返回值写0,导致用户态write失败。
    ElmerZhang
        26
    ElmerZhang  
       2015-04-14 18:33:18 +08:00   2
    write系统调用消耗的CPU很少了
    ryd994     27
    ryd994  
       2015-04-14 23:35:06 +08:00
    @bellchu 26楼
    bellchu
        28
    bellchu  
       2015-04-15 09:48:31 +08:00
    @ryd994 这不是正好证明我的理解是正确的么。无IO或无延迟,大量system call积聚造成CPU占用率飙升。

    BTW,昨天去楼下苹果店用这些命令给新Macbook烤机,开了四个线程的yes,CPU 100%,无风扇的机器居然不是很烫。。。。有点想买了,除了他那个纠结的键盘之外。
    bellchu
        29
    bellchu  
       2015-04-15 10:02:14 +08:00
    @bellchu 再BTW,yes是纯输出的命令,而/dev/null是write only的设备。所以用yes才能演示楼主所说的大量写入的情况。

    cat /dev/zero首先是从/dev/zero读取,然后写入/dev/null。所以system call的数量是read/write各占一半。

    /dev/zero /dev/random /dev/null都是上世纪创造的东西了,现在很多人都在想怎么改良它们。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1634 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 16:21 PVG 00:21 LAX 09:21 JFK 12:21
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86