OCaml-执行Lwt线程的Parmap挂起执行

OCaml-执行Lwt线程的Parmap挂起执行,ocaml,ocaml-lwt,Ocaml,Ocaml Lwt,这是对这一问题的后续行动: 我正在尝试运行以下代码: open Lwt open Cohttp_lwt_unix let server_content2 x = "in server content x" |> print_endline ; Client.get (Uri.of_string ("http://localhost:8080/"^x)) >>= fun (_, body) -> (Cohttp_lwt.Body.to_

这是对这一问题的后续行动:

我正在尝试运行以下代码:

open Lwt
open Cohttp_lwt_unix

let server_content2 x  =
    "in server content x" |> print_endline ;
    Client.get (Uri.of_string ("http://localhost:8080/"^x)) >>= fun (_, body) ->
        (Cohttp_lwt.Body.to_string body) >|= fun sc -> sc
        ;;
let reyolo () =
    List.init 10 (fun i -> server_content2 (string_of_int i) ) ;;
let par () = 
    let yolo = reyolo () in
    "in par" |> print_endline;
    Parmap.pariter 
        ~ncores:4 
        (fun p ->  "before run" |> print_endline ; "content:"^(Lwt_main.run p) |> print_endline  ; "after run" |> print_endline ) 
        (Parmap.L yolo);;

par ()

我预计这将执行10个远程连接。 我得到的是PAR函数<代码> LWTHEMAN。运行< /COD>似乎在进行实际远程调用之前卡住。

我怀疑这可能有什么意义,但假设响应的服务器是用python制作的,看起来像这样:

import subprocess
from bottle import run, post, request, response, get, route

@route('/<path>',method = 'GET')
def process(path):
    print(path)
    return "yolo"

run(host='localhost', port=8080, debug=True)

导入子流程
从瓶子导入运行、发布、请求、响应、获取、路由
@路由(“/”,方法=“GET”)
def进程(路径):
打印(路径)
返回“yolo”
运行(host='localhost',port=8080,debug=True)

问题在于,启动请求的对服务器内容2的调用发生在父进程中。然后,代码尝试在
Parmap
生成的子进程中完成它们。Lwt在这里中断:一般来说,它不能跨
分支跟踪I/O


如果在列表
yolo
中存储thunk或arguments,并延迟对
server\u content2
的调用,以便它们在子进程中完成,则请求应该可以工作。为此,请确保调用发生在
Parmap.pariter

的回调中,我可以响应一个更简单的示例;我高度怀疑这是最低限度的。在其他更改中,您是否能够删除Parmap的使用,并用Unix.fork替换它?还是什么都没有?我简化了这个例子。关于第二部分,Parmap是这个问题的关键元素,因为我想将远程连接集成到已经使用Parmap的现有程序中。摆脱Parmap最终要比为远程get/post(例如使用套接字)找到/实现其他解决方案付出更多的工作。我在这里要做的是,在程序中创建几个本地模块,并将Parmap的源代码复制到这些模块中,从而内联Parmap。然后,我将精简生成的组合程序,希望只剩下对
fork
的调用。我还将尝试将10个元素的列表减少到2甚至1。不用担心,如果你看一下Parmap,如果核心数小于扇出数,它的行为会有所不同,如果没有必要,这有助于消除。或者,熟悉Parmap的人可以直接回答这个问题,但是我不得不听从这样一个人:)@antron经过更多的测试,我得出了一个结论:挂断线程的第二个原因是服务器的错误行为。现在我使用的是C++中的JSON-RPC服务器,没有这样的事情发生。所以你提供的原始问题的答案是正确的。如果你把它作为答案贴出来,我会把它标记为正确答案。