如何安全地杀死从属内核?

发布于 2024-10-20 22:33:09 字数 338 浏览 0 评论 0原文

LinkClose[link] “不一定终止另一端的程序 正如文档中所说的“连接的”。有没有办法杀死 从属内核的进程是否安全?

编辑:

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

LinkClose[link] "does not necessarily terminate the program at the other end
of the connection" as it is said in the Documentation. Is there a way to kill the
process of the slave kernel securely?

EDIT:

In really I need a function in Mathematica that returns only when the process of the slave kernel has already killed and its memory has already released. Both LinkInterrupt[link, 1] and LinkClose[link] do not wait while the slave kernel exits. At this moment the only such function is seemed to be killProc[procID] function I had showed in one of answers at this page. But is there a built-in analog?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柠檬心 2024-10-27 22:33:09

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

At this moment I know only one method to kill the MathKernel process securely. This method uses NETLink and seems to work only under Windows and requires Microsoft .NET 2 or later to be installed.

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]

Any suggestions or improvements will be appreciated.

Edit:

The more correct method:

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

Edit 2:

Even more correct method:

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];
    ]
   ];
她比我温柔 2024-10-27 22:33:09

托德·盖利在新闻组中回答了我的问题。解决方案是向从属内核发送一个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] 函数。

Todd Gayley has answered my question in the newsgroup. The solution is to send to the slave kernel an MLTerminateMessage. From
top-level code:

   LinkInterrupt[link, 1] (* An undocumented form that lets you pick 
the message type *)

In C:

   MLPutMessage(link, MLTerminateMessage);

In Java using J/Link:

   link.terminateKernel();

In .NET using .NET/Link:

   link.TerminateKernel();

EDIT:

I have discovered that in standard cases when using LinkInterrupt[link, 1]
my operating system (Windows 2000 at the moment) releases physical memory
only in 0.05-0.1 second beginning with a moment of execution of
LinkInterrupt[link, 1] while with LinkClose[link] it releases physical
memory in 0.01-0.03 second (both values include the time, spent on execution
of the command itself). Time intervals were measured by using SessionTime[]
under equal conditions and are steadily reproduced.

Actually I need a function in Mathematica that returns only when the process of the slave kernel has already killed and its memory has already released. Both LinkInterrupt[link, 1] and LinkClose[link] do not wait while the slave kernel exits. At this moment the only such function is seemed to be killProc[procID] function I had showed in another answer at this page.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文