- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
尽管等待 linux 手册页 1很好地解释了您需要 wait()
来让子进程不变成僵尸,它根本没有说明原因。
我计划我的程序(这是我的第一个多线程程序,请原谅我的天真)围绕一个 for(;;)
ever 循环启动子进程,该子进程获取 exec()
ed 并肯定会自行终止。
我不能使用 wait(NULL)
因为这使得并行计算变得不可能,因此我可能必须添加一个存储子 pid 的进程表并且必须使用 waitpid
- 不是立即,而是在一段时间后 - 这是一个问题,因为 child 的运行时间从几微秒到几分钟不等。如果我太早使用 waitpid
,我的父进程会被阻塞,当我太晚使用它时,我会被僵尸淹没,不能再 fork()
了,这不是只对我的过程不利,但可能会导致整个系统出现意外问题。
我可能必须编写一些逻辑来使用一些最大数量的子级并在达到该数量时阻止父级 - 但这应该没有必要,因为大多数子级很快就会终止。我能想到的另一个解决方案(创建一个两层父进程来生成并发子进程,这些子进程又同时为孙子进程生成和 wait
)现在对我来说太复杂了。可能我还可以找到一个非阻塞函数来检查 child 并仅在他们终止时使用 waitpid
。
不过问题是:
为什么 Linux 会保留僵尸?为什么我必须等待我的 child ?这是为了对父进程实现纪律吗?在使用 Linux 的数十年中,我从未从僵尸进程中得到任何有用的东西,我不太了解僵尸进程作为“功能”的有用性。
如果答案是父进程需要找到一种方法来查明它们的子进程发生了什么,那么看在上帝的份上,没有理由仅仅因为存在僵尸进程就将僵尸进程视为正常进程并禁止创建非僵尸进程僵尸太多了。在我目前正在开发的系统上,我只能在一切都停止之前产生 400 到 500 个进程(这是一个维护不善的 CentOS 系统,运行在我能找到的最便宜的 VServer 上——但 400 个僵尸仍然少于几 kB 的信息)
最佳答案
I'll probably have to add a process table that stores the child pids and have to use waitpid - not immideately, but after some time has passed - which is a problem, because the running time of the children varies from few microseconds to several minutes. If I use waitpid too early, my parent process will get blocked
查看 documentation for waitpid
.您可以使用 WNOHANG
选项告诉 waitpid
不阻塞(即,如果没有 child 要收割,则立即返回)。此外,您不需要为 waitpid
提供 PID。您可以指定 -1
,它将等待任何 child 。因此,如下调用 waitpid
符合您的无阻塞约束和无保存 pids 约束:
waitpid( -1, &status, WNOHANG );
如果您真的不想正确处理进程创建,那么您可以通过 fork 两次、收割子进程并将exec
给孙子:
pid_t temp_pid, child_pid;
temp_pid = fork();
if( temp_pid == 0 ){
child_pid = fork();
if( child_pid == 0 ){
// exec()
error( EXIT_FAILURE, errno, "failed to exec :(" );
} else if( child_pid < 0 ){
error( EXIT_FAILURE, errno, "failed to fork :(" );
}
exit( EXIT_SUCCESS );
} else if( temp_pid < 0 ){
error( EXIT_FAILURE, errno, "failed to fork :(" );
} else {
wait( temp_pid );
}
在上面的代码片段中,子进程fork了自己的子进程,立即存在,然后立即被父进程收割。孙子是孤儿,由 init
收养,将自动收割。
Why does Linux keep zombies at all? Why do I have to wait for my children? Is this to enforce discipline on parent processes? In decades of using Linux I have never got anything useful out of zombie processes, I don't quite get the usefulness of zombies as a "feature". If the answer is that parent processes need to have a way to find out what happened to their children, then for god's sake there is no reason to count zombies as normal processes and forbid the creation of non-zombie processes just because there are too many zombies.
您还建议如何有效地检索进程的退出代码?问题是 PID <=> 退出代码(等)的映射必须是一对一的。如果内核在进程退出时立即释放进程的 PID,无论是否接收,然后新进程继承相同的 PID 并退出,您将如何处理为一个 PID 存储两个代码?感兴趣的进程将如何检索第一个进程的退出代码?不要仅仅因为您不关心退出代码就认为没有人关心退出代码。您认为是麻烦/错误的内容被广泛认为是有用且干净的。
On the system I'm currently developing for I can only spawn 400 to 500 processes before everything grinds to halt (it's a badly maintained CentOS system running on the cheapest VServer I could find - but still 400 zombies are less than a few kB of information)
将一个被广泛接受的内核行为作为替罪羊来表达对维护不善/廉价系统的明显不满似乎是不对的。
通常,您的最大进程数仅受内存限制。您可以通过以下方式查看您的限制:
cat /proc/sys/kernel/threads-max
关于linux - 为什么我必须为子进程设置 `wait()`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54225763/
我在一次采访中遇到过这个问题。 线程中wait和wait on time有什么区别? 我知道 wait 方法 导致当前线程等待,直到另一个线程调用此对象的 notify() 方法或 notifyAll
我在这里得到了一个 java 代码片段,这让我想知道调用 wait() 和 this.wait() 之间的区别是什么。 假设您有一个类,该类具有获取资源的方法并且是同步的。通常,如果资源不可用,我会在
我知道如何使用 wait_event 在 Linux 内核队列中等待以及如何唤醒它们。 现在我需要弄清楚如何同时在多个队列中等待。我需要多路复用多个事件源,基本上以类似于 poll 或 select
c系统编程中wait(null)和wait(&status)有什么区别? 指针状态的内容是什么? 最佳答案 如果您调用 wait(NULL) ( wait(2) ),您只会等待任何子进程终止。使用 w
设想: 用户单击 View 上的按钮 这会调用 ViewModel 上的命令 DoProcessing 考虑到 View 和 ViewModel 的职责,Wait 光标是如何以及在哪里设置的? 为了清
我在使用 Selenium 的代码中看到了 FluentWait 和 WebDriverWait。 FluentWait 使用轮询技术,即它将在每个固定时间间隔轮询特定的 WebElement。我想知
我编写了以下代码,其中 start 方法应该等待,直到 stop 方法通知它。但是在执行过程中,尽管我已指定它等待,但启动方法下面的日志行会被打印。下图是我的start方法实现如下。 private
我有以下连接到 SignalR Hub 的代码 private static async Task StartListening() { try {
我对线程中的 wait() 方法如何工作感到很困惑。假设我写: public class test3 { public static void main(String args[]){
在使用 Java 线程原语构造线程安全有界队列时 - 这两种构造之间有什么区别 创建显式锁定对象。 使用列表作为锁并等待它。 示例 1 private final Object lock = new
故事: 在 Java selenium 语言绑定(bind)中有一个 FluentWait class ,这允许严格控制如何检查预期条件: Each FluentWait instance defin
wait-die 和 wound-wait 算法有什么区别? 这两种死锁预防技术似乎都在做同样的事情:回滚旧进程。 两者有什么区别? 请提供一个合适的例子来对比这两种算法。 最佳答案 Wait-Die
在 Java 线程转储中,您可以看到堆栈跟踪中提到的锁。 似乎有三种信息: 1: - locked (a java.io.BufferedInputStream) 2: - waiting to l
以下代码运行大约需要 20 秒。然而,取消注释 do! 后只用了不到一秒的时间。为什么会有这么大的差异? 更新:使用ag.Add时需要9秒。我已经更新了代码。 open FSharpx.Control
我在 ASP.NET WebForms 网站上有一个服务器端点击事件。在这种情况下,我调用一个方法,该方法又调用其异步合作伙伴方法,在调用中添加 .Wait()。 此方法然后向下几个级别(即,调用另一
有 3 种状态的线程处于 Activity 状态但既不运行也不可运行:- sleep 已阻止 正在等待 当线程执行 sleep() 方法时,它会在其参数指定的时间段(比如几毫秒)内从运行状态进入休眠状
考虑以下代码 public class ThreadTest1 { private static final long startTime = System.currentTimeMillis();
我有一个使用线程的 Java 应用程序,它使用多个 Lock 对象实例来同步对公共(public)资源的访问。 现在,作为性能测量的一部分,我想测量每个线程在每个锁中花费的时间。到目前为止,我已经尝试
我写了下面这段代码: let first_row = rows_stream.take(1).wait(); 并收到以下错误(当我真正想要访问该元素时): found struct `futures:
我使用了两个命令来等待设备启动:adb 等待设备和 adb 等待设备。两者似乎都在等待设备启动,我发现它们的行为没有任何区别。他们的行为有什么不同吗? 添加更多关于我所做的信息: 所以这就是我所做的,
我是一名优秀的程序员,十分优秀!