我通过授权服务的“AuthorizationExecuteWithPrivileges”调用使用root / admin priveleges执行大量shell命令。问题是,经过一段时间(10-15秒,可能是100个shell命令),程序在调试器中停止响应此错误:
无法分叉:错误35
然后在应用程序运行时,我无法启动任何其他应用程序。我研究了这个问题,显然这意味着没有更多的线程供系统使用。但是,我使用Activity Monitor进行了检查,我的应用只使用了4-5个线程。
要解决这个问题,我认为我需要做的是将shell命令分成一个单独的线程(远离主线程)。我之前从未使用过线程,我不确定从哪里开始(我找不到全面的例子)
由于
答案 0 :(得分:7)
正如Louis Gerbarg已经指出的那样,你的问题与线程无关。我已经相应地修改了你的标题和标签。
我通过授权服务的“AuthorizationExecuteWithPrivileges”调用使用root / admin priveleges执行大量shell命令。
不要那样做。该函数仅存在,因此您可以将root:admin所有权和setuid模式位还原到要以root身份运行的工具。
我们的想法是,您应该将应该作为root运行的代码分解为一个完全独立的程序,而不需要以root身份运行的部分,以便需要root的部分可以拥有它(通过setuid位)并且不需要root的部分可以没有它(通过没有setuid)。
代码示例位于Authorization Services Programming Guide。
问题是,经过一段时间(10-15秒,可能是100个shell命令),程序在调试器中停止响应此错误:
couldn't fork: errno 35
呀。您一次只能运行几百个进程。这是操作系统强制执行的限制。
这是一个软限制,这意味着你可以提高它 - 但只能达到你无法提出的硬限制。查看limit
和limit -h
的输出(在zsh中;我不知道其他shell)。
在运行更多进程之前,您需要等待进程完成。
然后在应用程序运行时,我无法启动任何其他应用程序。
因为您已经在运行尽可能多的进程。 x-100进程限制是按用户进行的,而不是按进程进行的。
我研究了这个问题,显然这意味着没有更多的线程供系统使用。
不,它没有。
错误代码用于很多事情。 EAGAIN
(35,“资源暂时不可用”)可能意味着在启动线程的系统调用设置时不再有线程,但这并不意味着由另一个系统调用或函数设置时。
您明确引用的错误消息表示它是由fork
设置的,这是系统调用以启动新的进程,而不是新的线程 。在这种情况下,EAGAIN
表示“您已经在运行尽可能多的进程”。请参阅the fork manpage。
但是,我使用Activity Monitor进行了检查,我的应用只使用了4-5个线程。
请参阅?
要解决这个问题,我认为我需要做的是将shell命令分成一个单独的线程(远离主线程)。
每个线程启动一个进程只会帮助您更快地耗尽进程。
我之前从未使用过线程......
听起来你还没有,因为你所指的功能会启动一个进程,而不是一个线程。
答案 1 :(得分:3)
这不是关于线程(至少不是应用程序中的线程)。这是关于系统资源的。这些分叉进程中的每一个都消耗至少1个内核线程(可能更多),一些vnode和许多其他东西。最终,系统将不允许您生成更多进程。
您遇到的第一个限制是管理限制。系统可以支持更多,但可能会导致性能下降和其他问题。你通常可以通过各种各样的mecahanisms来提升它们,比如sysctls。一般来说这样做是个坏主意,除非你有一个特殊的(特殊的)工作量,你知道这个工作量会从特定的调整中受益。
提高这些限制的机会无法解决您的问题。虽然调整这些限制可能会让您运行一段时间,但为了实际修复它,您需要找出资源未返回系统的原因。基于你上面描述的内容,我猜你的分叉进程永远不会退出。