如何在Julia中获取正在运行的外部命令的系统进程id



问题:我想知道一个有缺陷的外部程序的系统进程ID,该程序作为命令从julia工作进程中调用。其中一些外部工具调用将导致该外部程序的内存泄漏。

我想监控这些系统调用的内存消耗,这样,如果它们超过内存阈值,我就可以杀死它们,而不是等待所有系统内存被消耗,以及某种任意内存分配错误影响系统上运行的东西。

我正在寻找类似于非阻塞的东西:

pid = @async run( `my_external_program` )

其中pid是my_external_program 的系统进程id

作弊。

#### In (executable) file "sleep_inner_wrapper"
#!/bin/bash
sleep 20                       # the actual command you want to run
echo -e "Finished sleepingn"  # the event you want to detect on exit

### In (executable) file "sleep_outer_wrapper"
#!/bin/bash
./sleep_inner_wrapper &
jobs -p > mypid                # bingo


如果你不扼杀这个过程,你的julia会话:

julia> @async( run( `./sleep_outer_wrapper`))
Task (waiting) @0x00007f97a6303850
julia> pid = parse(Int64, chomp(readline(open("mypid","r"))))
10944
                          ... twenty seconds later ...
julia> Finished sleeping


如果你决定终止进程,你的julia会话:

julia> @async( run( `./sleep_outer_wrapper`))
Task (waiting) @0x00007f97a63036c0
julia> pid = parse(Int64, chomp(readline(open("mypid","r"))))
10930
julia> run(Cmd(ByteString["kill";"-9";"$pid"]))

现在,您可以异步生成进程,并使用spawn获取句柄,例如

process = spawn(`sleep 10`)

这返回一个CCD_ 2对象。不幸的是,我现在看不到一个简单的方法来获得pid,但这应该是可能的。process.handle字段是指向底层libuv进程结构的指针。您可以通过将结构转换为Julia对象来实现这一点,或者您可以在Julia的源代码中编写一个小的C函数来获得它,例如

int jl_get_proc_pid (uv_process *proc) { return proc.pid }
# In Julia
pid(process::Process) = ccall(:jl_get_proc_pid, (Ptr{Void},), Int, process.handle)

这可能是一个为Julia做补丁的好机会,尽管如果有人告诉我我错了,那就太好了,而且有一种更容易的方法我忽略了:)

现在只需通过getpid(::Base.Process)支持:https://docs.julialang.org/en/v1/base/base/#Base.Libc.getpid

相关内容

最新更新