我正在尝试并行工作。我试图让子进程每个取一部分工作,然后等待工作从父进程完成。
下面的解决方案似乎适用于小示例:
let par_iter (items: 'i list) ~(f: 'i -> unit): unit =
let orig_pid = Unix.getpid () in
let rec loop = function
| [] -> ()
| h :: t ->
match Unix.fork () with
| 0 -> f h
| _ -> loop t
in
loop items;
if Unix.getpid () = orig_pid then
List.iter items ~f:(fun _ -> ignore @@ Unix.wait ())
else
exit 0
用法:
let () =
par_iter [1; 2; 3; 4] ~f:do_something_with_an_int;
当有多个子流程时,Unix.wait
的合同我不是很清楚。在这里,我依赖于wait
和n
时间将等待所有且只有n
子进程完成的行为。
这个解决方案依赖于未定义的行为吗?是否有另一种方法来正确地实现par_iter
,使其在子进程上产生工作并等待工作完成?
在OCaml 4.14.0上测试
如果原始父进程已经有一些子进程,那么这可能会失败。因此,恕我直言,它不能作为通用库使用。您应该使用Unix.waitpid
来专门等待您创建的进程。