LinkClose[link]
正如文档中所说,“不一定会在连接的另一端终止程序”。有没有办法安全地杀死从内核的进程?
编辑:
实际上,我需要Mathematica中的一个函数,它仅在从内核的进程已经终止并且它的内存已经释放时才返回。从内核退出时两者LinkInterrupt[link, 1]
都LinkClose[link]
不要等待。目前,唯一这样的功能似乎是killProc[procID]
我在此页面的一个答案中显示的功能。但是有内置的模拟吗?
LinkClose[link]
正如文档中所说,“不一定会在连接的另一端终止程序”。有没有办法安全地杀死从内核的进程?
编辑:
实际上,我需要Mathematica中的一个函数,它仅在从内核的进程已经终止并且它的内存已经释放时才返回。从内核退出时两者LinkInterrupt[link, 1]
都LinkClose[link]
不要等待。目前,唯一这样的功能似乎是killProc[procID]
我在此页面的一个答案中显示的功能。但是有内置的模拟吗?
目前我只知道一种MathKernel
安全地终止进程的方法。此方法使用NETLink
并且似乎仅在 Windows 下有效,并且需要安装 Microsoft .NET 2 或更高版本。
killProc[processID_] := If[$OperatingSystem === "Windows",
Needs["NETLink`"];
Symbol["LoadNETType"]["System.Diagnostics.Process"];
With[{procID = processID},
killProc[procID_] := (
proc = Process`GetProcessById[procID];
proc@Kill[]
);
];
killProc[processID]
];
(*Killing the current MathKernel process*)
killProc[$ProcessID]
任何建议或改进将不胜感激。
更正确的方法:
Needs["NETLink`"];
LoadNETType["System.Diagnostics.Process"];
$kern = LinkLaunch[First[$CommandLine] <> " -mathlink -noinit"];
LinkRead[$kern];
LinkWrite[$kern, Unevaluated[$ProcessID]];
$kernProcessID = First@LinkRead[$kern];
$kernProcess = Process`GetProcessById[$kernProcessID];
AbortProtect[If[! ($kernProcess@Refresh[]; $kernProcess@HasExited),
$kernProcess@Kill[]; $kernProcess@WaitForExit[];
$kernProcess@Close[]];
LinkClose[$kern]]
更正确的方法:
Needs["NETLink`"];
LoadNETType["System.Diagnostics.Process"];
$kern = LinkLaunch[First[$CommandLine] <> " -mathlink -noinit"];
LinkRead[$kern];
LinkWrite[$kern, Unevaluated[$ProcessID]];
$kernProcessID = First@LinkRead[$kern];
$kernProcess = Process`GetProcessById[$kernProcessID];
krnKill := AbortProtect[
If[TrueQ[MemberQ[Links[], $kern]], LinkClose[$kern]];
If[TrueQ[MemberQ[LoadedNETObjects[], $kernProcess]],
If[! TrueQ[$kernProcess@WaitForExit[100]],
Quiet@$kernProcess@Kill[]; $kernProcess@WaitForExit[]];
$kernProcess@Close[]; ReleaseNETObject[$kernProcess];
]
];
Todd Gayley 在新闻组中回答了我的问题。解决方案是向从内核发送一个MLTerminateMessage
. 从顶级代码:
LinkInterrupt[link, 1] (* An undocumented form that lets you pick
the message type *)
在 C 中:
MLPutMessage(link, MLTerminateMessage);
在 Java 中使用 J/Link:
link.terminateKernel();
在 .NET 中使用 .NET/Link:
link.TerminateKernel();
编辑:
我发现在标准情况下,当使用LinkInterrupt[link, 1]
我的操作系统(目前是 Windows 2000)时,仅在 0.05-0.1 秒内释放物理内存,从执行时刻开始,
LinkInterrupt[link, 1]
而LinkClose[link]
它在 0.01-0.03 秒内释放物理内存(这两个值包括时间,花在执行命令本身上)。时间间隔是通过SessionTime[]
在同等条件下使用来测量的,并且可以稳定地复制。
实际上,我需要Mathematica中的一个函数,该函数仅在从内核的进程已经杀死并且它的内存已经释放时才返回。从内核退出时两者LinkInterrupt[link, 1]
都LinkClose[link]
不要等待。目前,唯一的此类功能似乎是killProc[procID]
我在此页面的另一个答案中显示的功能。