命令行工具从NSTask运行缓慢,而从Terminal运行迅速

时间:2019-07-31 10:17:26

标签: macos child-process nstask

我编写了一个cmdline工具,通常需要15到20秒才能完成。

执行任务时,它至少每秒通过stdout输出一次进度。

当我从Terminal.app运行命令时,它的执行速度尽可能快,例如不到20秒。

但是当我通过NSTask通过GUI应用程序运行该工具时,该工具至少需要花费3-5倍的时间。

GUI应用程序使用NSPipeNSFileHandleReadCompletionNotification上的观察者来监视该工具的输出,并且该输出频繁到达(例如,至少每秒一次)。

我尝试将NSTask的{​​{1}}属性设置为较高的值(最大0x21),没有任何改善。

任务从线程(通过qualityOfService调用)启动,并通过调用其performSelectorInBackground方法等待任务完成。

我通过活动监视器进行了检查:

  • GUI应用程序和工具都不会进入“应用程序休息”模式。
  • 我可以看到该工具从Terminal运行时会占用30%的CPU时间,而从GUI应用程序运行时通常会降至10%以下。

我已经在两台配置完全不同的计算机上看到了10.13.6上的问题。我还没有机会在其他操作系统版本上进行测试,尽管如果在10.13版本中无法正常运行,那已经足够糟糕了。

是什么原因导致该工具受到限制?

该工具大部分时间都花在内核上,因为它调用waitUntilExit,后者会广泛扫描文件系统。我想知道这是否是问题的一部分。

还可以有人建议以其他方式运行该工具的替代方法,以使GUI应用程序可以控制其生命周期(即应作为子进程运行),让其将参数传递给该工具并读取其stderr。和标准输出管道?

1 个答案:

答案 0 :(得分:1)

您始终可以通过以下方法启动NSTask来提高其优先级:

nice -n *priority* *command* *arguments* 

其中优先级必须为负数,最大为-20,负数越大,优先级越高。

但是,您将需要超级用户权限才能启动这样的命令。

您可以在这里阅读有关内容:

https://ss64.com/osx/nice.html

或此处:

https://superuser.com/questions/42817/is-there-any-way-to-set-the-priority-of-a-process-in-mac-os-x