【发布时间】:2017-11-14 20:25:31
【问题描述】:
我正在查看以下 OCaml 代码,它尝试打开一个子进程,为其提供一些输入,然后收集它在 stdout 或 stderr 上产生的所有输出。但是它首先从 stdout 读取所有内容,然后从 stderr 读取所有内容这一事实似乎很可疑——如果子进程恰好向 stderr 写入了很多东西,那么结果似乎会是死锁。
let rec output_lines (output : string list) (chan : out_channel) : unit =
ignore (List.map (output_string chan) output); flush chan
let async_command
(name : string)
(arguments : string list)
: (in_channel * out_channel * in_channel) =
Unix.open_process_full
(name ^ " " ^ (String.concat " " arguments))
(Unix.environment ())
let sync_command
(name : string)
(arguments : string list)
(input : string list) : (string list * string list) =
let (o, i, e) = async_command name arguments in
output_lines input i;
let out, err = (input_lines o, input_lines e) in
let status = Unix.close_process_full (o, i, e) in
begin match status with
| Unix.WEXITED x -> if x != 0 then raise (Shell_error (unlines err))
| Unix.WSIGNALED x -> if x = Sys.sigint then raise Sys.Break
| Unix.WSTOPPED x -> if x = Sys.sigint then raise Sys.Break
end;
(out, err)
应该如何解决这个问题? (更好的是,我应该在已经实现此功能的地方使用哪个库?)
【问题讨论】:
-
我同意你的担忧。在我看来,您也可能出于类似原因在
output_lines中陷入僵局。 -
顺便说一下,它会首先从
stderr读取,因为 OCaml 从右到左进行评估(虽然没有指定,但这是通常发生的情况)。这并不是说这样就可以解决死锁问题,仅供参考。 -
谢谢。 (是的,output_lines 也是有问题的。幸运的是,我碰巧知道,在我的应用程序中,这里的数据会很小。)
标签: ocaml