Ocaml 如何使用Lwt从特定目录正确启动进程

Ocaml 如何使用Lwt从特定目录正确启动进程,ocaml,ocaml-lwt,Ocaml,Ocaml Lwt,使用函数Sys.getpwd、Lwt\u unix.chdir和Lwt\u process.exec,可以轻松地从特定目录启动进程: 使用Sys.getpwd保存当前工作目录 使用Lwt\u unix.chdir更改到特定目录 使用Lwt\u process.exec启动外部进程 使用Lwt\u unix.chdir更改为保存的当前工作目录 此逻辑有缺陷,因为它允许调度程序在第一次调用Lwt_unix.chdir和调用Lwt_process.exec后运行另一个线程,这将导致此线程在特殊目录中运

使用函数
Sys.getpwd
Lwt\u unix.chdir
Lwt\u process.exec
,可以轻松地从特定目录启动进程:

  • 使用
    Sys.getpwd
    保存当前工作目录
  • 使用
    Lwt\u unix.chdir
    更改到特定目录
  • 使用
    Lwt\u process.exec
    启动外部进程
  • 使用
    Lwt\u unix.chdir
    更改为保存的当前工作目录

  • 此逻辑有缺陷,因为它允许调度程序在第一次调用
    Lwt_unix.chdir
    和调用
    Lwt_process.exec
    后运行另一个线程,这将导致此线程在特殊目录中运行,而不是在保存的当前目录中运行。是否可以使用Lwt从特殊目录轻松启动进程,而不引入我描述的竞争条件?

    您可以使用一些同步原语(如
    Lwt\u互斥体)来保护当前工作目录。但是这里有一些警告,假设你有这个链条:

    lock dir_guard >> chdir dir >> exec proc >> chdir dir' >> unlock dir_guard
    
    这不允许在进程
    proc
    执行其任务的整个过程中更改目录。这可能是谨慎和不必要的。以下代码没有此问题:

    let exec_in_folder guard dir proc = 
      with_lock guard (fun () -> 
         chdir dir >>= fun () -> return (exec proc)) >>= fun proc_t ->
      proc_t
    

    但是,这段代码有一个问题,它只有在进程以原子方式启动时才是正确的,也就是说,如果在进程启动过程中不存在重新调度的可能性,这将允许其他线程干扰并更改当前文件夹。为了证明它是原子的,您可以读取源代码,或者实现自己启动的进程,这将有这样的保证。如果您将阅读代码,那么您将发现,该进程是使用
    spawn
    函数创建的,这一瞬间将执行
    fork
    ,没有任何穿插的线程。是的,这个代码是正确的

    谢谢你详细的回答。您的
    exec\u in_folder
    函数似乎“忘记”了在函数启动之前保存和恢复cwd。我想,整个程序需要协作并使用一个全局互斥来保护cwd,最好有一个本地解决方案,即一个只需查看当前代码部分即可被视为正确的解决方案我认为这应该在Lwt中作为一个问题报告。你呢?是的,为了简洁起见,我把细节遗漏在了范围之外。我不觉得lwt有任何问题(期望他们能够更好地记录
    过程
    )。工作目录只是一个隐藏的全局变量。但是,在lwt中可以做的是,他们可以向
    exec
    函数添加
    ?working_dir
    选项,就像Janestreet的伙计们在他们的
    Async
    库中所做的那样。在引擎盖下,他们只是以阻塞的方式改变cwd,所以没有比赛条件是可能的。迈克尔,对不起,我来晚了。没有提到你的评论。我的错,我忘了提到你。:)我在《我想我将在未来几周内准备一份公关报告》中对此发表了一篇文章——我现在有一个提灯时间表。:)因为你已经快一个星期没有回复了,每个人都有机会接受,所以我会接受你的回复。