【问题标题】:How do I prevent message flooding with open_port?如何使用 open_port 防止消息泛滥?
【发布时间】:2016-10-13 00:00:16
【问题描述】:

我正在尝试使用标准输入一次一行地读取 100gb 文件

Port = open_port({fd, 0, 1}, [in, binary, {line, 4096}]),

但这会使我的系统充满消息,直到我用完 ram。有没有办法让它像 {active, once} 与端口?还有 io:get_line() 但我想知道这是否可行。

【问题讨论】:

    标签: erlang erl


    【解决方案1】:

    不,对端口没有流量控制,因此如果处理速度不够快,则应使用另一种处理方法。您可以使用

    STDIN 上设置二进制模式
    ok = io:setopts(standard_io, [binary]),
    

    如果您使用的是版本 17 或更高版本(存在影响性能的错误),则可以使用 file:read_line(standard_io) 阅读它。

    【讨论】:

    • 嘿 Hynek,谢谢你,这确实有效。我正在解析的 json 大小为 100k 或更大,并且 read_line 似乎在找到新行之前返回,可能是因为它超出了缓冲区大小。设置诸如 {readahead, X} 之类的东西会返回一个标准 io 不支持的错误。有什么办法吗?
    • @ForeverConfused:我不知道readahead是否可以设置为standard_io。您可以使用变通方法检查是否存在行尾并连接未完成的行。它将在内存中执行复制,但我不知道任何其他解决方案。
    • 我试过了,file:get_chars 并自己做缓冲区。但即使我一次只缓冲 1000 行,它似乎由于某种原因导致内存溢出。我最终不得不将标准输入传输到 netcat,然后将 erlang 与 {active,once} 一起使用
    • @ForeverConfused:你使用的是二进制文件吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 1970-01-01
    相关资源
    最近更新 更多