Как правильно запустить процесс из определенного каталога с помощью Lwt
Легко запустить процесс из определенного каталога с помощью Lwt, используя функции Sys.getpwd
, Lwt_unix.chdir
а также Lwt_process.exec
:
- использование
Sys.getpwd
сохранить текущий рабочий каталог - использование
Lwt_unix.chdir
перейти в конкретный каталог - использование
Lwt_process.exec
запустить внешний процесс - использование
Lwt_unix.chdir
перейти в сохраненный текущий рабочий каталог
Эта логика ошибочна, так как позволяет планировщику запускать другой поток после первого вызова Lwt_unix.chdir
и после звонка Lwt_process.exec
что приведет к запуску этого потока в специальном каталоге, а не в сохраненном текущем каталоге. Можно ли легко запустить процесс из специального каталога с помощью Lwt, не вводя условие гонки, такое как описанное мной?
1 ответ
Вы можете защитить свой текущий рабочий каталог с помощью некоторого примитива синхронизации, например Lwt_mutex
, Но здесь есть некоторая оговорка, предположим, у вас есть эта цепочка:
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
без каких-либо перемежающихся нитей. Так что да, этот код правильный.