3

我通过授权服务的“AuthorizationExecuteWithPrivileges”调用以 root/admin 权限执行了大量的 shell 命令。问题是一段时间后(10-15 秒,可能是 100 个 shell 命令),程序在调试器中停止响应并出现以下错误:

无法分叉:errno 35

然后在应用程序运行时,我无法启动更多应用程序。我研究了这个问题,显然这意味着系统没有更多线程可供使用。但是,我使用活动监视器进行了检查,我的应用程序只使用了 4-5 个线程。

为了解决这个问题,我认为我需要做的是将 shell 命令分离到一个单独的线程中(远离主线程)。我以前从未使用过线程,我不确定从哪里开始(我找不到全面的例子)

谢谢

4

2 回答 2

7

正如 Louis Gerbarg 已经指出的那样,您的问题与线程无关。我已经相应地编辑了您的标题和标签。

我通过授权服务的“AuthorizationExecuteWithPrivileges”调用以 root/admin 权限执行了大量的 shell 命令。

不要那样做。该功能仅存在,因此您可以将 root:admin 所有权和 setuid 模式位恢复到您要以 root 身份运行的工具。

这个想法是,您应该将应该以 root 身份运行的代码与不需要以 root 身份运行的部分分离到一个完全独立的程序中,以便需要 root 的部分可以拥有它(通过 setuid 位)和不需要root的部分可以没有它(通过没有setuid)。

Authorization Services Programming Guide中有一个代码示例。

问题是一段时间后(10-15 秒,可能是 100 个 shell 命令),程序在调试器中停止响应并出现以下错误:

couldn't fork: errno 35

是的。您一次只能运行几百个进程。这是操作系统强制的限制。

这是一个软限制,这意味着你可以提高它——但只能达到硬限制,你不能提高它。查看limitand的输出limit -h(在 zsh 中;我不知道其他 shell)。

在运行更多进程之前,您需要等待进程完成。

然后在应用程序运行时,我无法启动更多应用程序。

因为您已经在运行尽可能多的进程。x-hundred-process 限制是每个用户,而不是每个进程。

我研究了这个问题,显然这意味着系统没有更多线程可供使用。

不,不是的。

errno 错误代码用于许多事情。EAGAIN(35,“资源暂时不可用”)可能意味着当由启动线程的系统调用设置时不再有线程,但这并不意味着当由另一个系统调用或函数设置时。

您引用的错误消息明确表示它是由启动新进程而不是新线程fork的系统调用设置的。在这种情况下,意味着“您已经在运行尽可能多的进程”。请参阅fork 手册页EAGAIN

但是,我使用活动监视器进行了检查,我的应用程序只使用了 4-5 个线程。

看?

为了解决这个问题,我认为我需要做的是将 shell 命令分离到一个单独的线程中(远离主线程)。

每个线程启动一个进程只会帮助您更快地用完进程。

我以前从未使用过线程……</p>

听起来您还没有,因为您所指的函数启动了一个进程,而不是一个线程。

于 2009-08-23T05:02:39.557 回答
3

这与线程无关(至少不是应用程序中的线程)。这是关于系统资源的。这些分叉进程中的每一个都消耗至少 1 个内核线程(可能更多)、一些 vnode 和许多其他东西。最终,系统将不允许您生成更多进程。

您遇到的第一个限制是管理限制。系统可以支持更多,但可能会导致性能下降和其他问题。您通常可以通过各种机制(如 sysctls)来提高这些。一般来说,这样做是一个坏主意,除非你有一个特定的(特殊的)工作负载,你知道会从特定的调整中受益。

提高这些限制的机会不会解决您的问题。虽然调整这些限制可能会使您运行更长时间,但为了实际修复它,您需要弄清楚为什么资源没有返回到系统。根据您上面描述的内容,我猜您的分叉进程永远不会退出。

于 2009-08-23T04:12:30.330 回答