如何安全地杀死奴隶内核?

时间:2011-03-08 06:51:26

标签: wolfram-mathematica mathlink

LinkClose[link]“不一定在另一端终止程序 连接“就像在文档中说的那样。有没有办法杀死它 奴隶内核安全过程?

修改

实际上我需要 Mathematica 中的一个函数,该函数仅在从属内核的进程已经被杀死且其内存已经释放时返回。从属内核退出时,LinkInterrupt[link, 1]LinkClose[link]都不会等待。此时唯一这样的函数似乎是我在本页的一个答案中显示的killProc[procID]函数。但是有没有内置模拟?

2 个答案:

答案 0 :(得分:1)

目前我只知道一种方法可以安全地终止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]]

编辑2:

更正确的方法:

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];
    ]
   ];

答案 1 :(得分:1)

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]函数。