【问题标题】:Emscripten - Is there a way to throttle writing to stdout?Emscripten - 有没有办法限制写入标准输出?
【发布时间】:2020-05-29 15:05:33
【问题描述】:

我正在运行一个使用 emscripten 编译为 wasm 的 C 工具。该工具适用于非常大的文件。在 CLI 上正常运行此工具时,操作通常会流式传输结果并在返回足够的数据后提前终止程序。例如,您可能会运行:

./tool <input-file> | head -n 100

该工具将在检测到 stdout 已被head 关闭后终止,实际上只读取一小部分输入。

问题在于带有 emscripten 的 stdout 似乎是异步的(通过覆盖 Module.print),因此该工具每次都运行完成。有没有办法让它在标准输出上阻塞,所以我只能读取我需要的内容然后终止该工具?

【问题讨论】:

  • 问题是带有 emscripten 的标准输出似乎是异步的 数据必须在某个地方。可能只是一个大缓冲区。你在什么操作系统上运行?如果您使用的是 Linux,您可以尝试使用 the stdbuf utility,如以下答案:stackoverflow.com/a/25548995/4756299
  • 对不起,如果我不是很清楚。这不是缓冲问题。恰恰相反。我有太多数据出来了,我希望能够告诉 WebAssembly 进程阻塞,直到我处理完已经收到的数据。

标签: javascript c webassembly emscripten


【解决方案1】:

您可以将输出重定向到文件,然后将任务置于后台。同时监控日志文件。当它达到 100 行时,杀死子 pid。

这样的一些应该可以工作:

rm -f /tmp/log
touch /tmp/log
./tool input_file > /tmp/log 2>&1 &
pid=$!

while sleep 1
do
    ret=`cat /tmp/log | wc -l`
    if [ "$ret" -ge 100 ]
    then
        kill $pid
        exit 0
    fi
done

我创建了一个空日志文件。这将避免在子进程创建它之前我们对其进行 cat 处理的竞争条件。 wc -l 将返回行数。将睡眠值更改为适合您的测试时间的值。

【讨论】:

  • 您甚至不需要 tmp 文件来执行此操作。你可以直接从 Module.print 中收集行,当你有足够的时候终止进程。问题是该工具同时会浪费很多周期。
【解决方案2】:

您需要实现一种方法来告诉您的工具停止。有很多方法可以做到这一点。想到的两个:

  1. 让它接受一个额外的参数来指示它应该停止的输出行数,然后用这个参数调用它。这是最简单的方法,也最容易实现。主要缺点是您需要提前知道最大行数,以便可以将其包含在调用参数中,并且tool 必须能够准确地知道如何将其转换为何时停止——但是如果是这样的话,听起来像,那么就这样做,你就完成了。

但我想如果你的工具不知道如何计算行数——也许它只是输出 blob,或者你有一些下游过滤器只计算 some 行到你的最大值和任何在这种情况下,您的工具需要一些其他功能来告诉它何时停止,那么这将不起作用,在这种情况下,请继续阅读...

  1. 使用回调。创建和导出另一个函数,例如tool_stop()。在您的 Module.print 覆盖函数中,在适当的时候调用 tool_stop()。在您的 C 代码中,创建一些标志,我们称之为 stop_processing,它对您的 tool 命令可见,对处理输入的函数也可见。在您的处理循环中(例如,在每个 fread 调用之前),您的 tool 命令检查此标志,如果已设置,它将停止处理(当我说“可见”时,这可能意味着您将其设为全局变量,如果您将永远不会运行多个并发调用,或者将其作为某些上下文数据的一部分,这些数据通过某些 init 调用分配并在进行 process() 或 stop() 调用时传递,然后通过 destroy() 释放调用。后一种方法通常更清洁、更可扩展且更易于维护,但工作量更大,因为您必须添加 init + destroy,并为每个函数定义和调用添加上下文指针)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多