【问题标题】:Terminate an NSTask and its children终止一个 NSTask 及其子任务
【发布时间】:2013-12-29 14:00:59
【问题描述】:

我正在使用 NSTask 执行一系列长时间运行的命令,如下所示:

commandToRun = @"command 1;command2";
NSArray *arguments = [NSArray arrayWithObjects:
                      @"-c",
                      commandToRun,
                      nil];
self.task = [[NSTask alloc] init];
[self.task setLaunchPath: @"/bin/sh"];
[self.task setArguments: arguments];
[self.task launch];

这将为 shell 创建一个进程,并为当时正在运行的任何命令(命令 1 或命令 2)创建一个子进程。如果我用[self.task terminate] 终止任务,它只会终止父进程。有没有办法识别和杀死孩子呢?

【问题讨论】:

  • 根据文档终止将 SIGTERM 发送到子任务。你确定你的子任务可以监听 SIGTERM 吗?
  • 不涉及 shell 的解决方案是为每个进程创建一个 NSTask。如果它们打算被链接,(a)您当前的代码不会这样做,并且(b)使用两个 NSTask,您可以从第一个的 terminationHandler 启动第二个。

标签: cocoa nstask


【解决方案1】:

这不是很优雅,但是您可以让sh 将子任务作为后台进程启动,然后按照here 使用shell 变量$! 将它们的PID 写入文件,阻塞直到每个后台进程完成以维护异步性:

commandToRun = @"command1 & echo $! > /tmp/childpid; wait $!; command2 & echo $! > /tmp/childpid; wait $!";

那么当你调用[self.task terminate]你也应该调用:

system("kill -9 `cat /tmp/childpid`");
...或类似的东西。

【讨论】:

  • 那行得通。实际上,这并不像我想的那样可怕。谢谢!
猜你喜欢
  • 2023-03-03
  • 2019-12-30
  • 2018-07-06
  • 1970-01-01
  • 2014-11-18
  • 2012-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多