是否可以采用流程? [英] Is it possible to adopt a process?

查看:131
本文介绍了是否可以采用流程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

进程A fork()进程B.

进程A死了,因此init采纳了B.

Process A dies and therefore init adopts B.

看门狗创建进程C.

C是否有可能采用init中的B?

Is it somehow possible for C to adopt B from init?

更新:

或者如果C是在A死前创建的,而没有init成为B的中间父代,那么甚至有可能让C直接采用B(当A死时)吗?

Or would it even be possible to have C adopt B directly (when A dies), if C were created prior to A's dead, without init becoming an intermediate parent of B?

更新1:

对于任何可能以我所描述的方式采用流程将是一件坏事或难以实现的事情,我也将不胜感激.

Also I would appreciate any comments on why having the possiblity to adopt a process the way I described would be a bad thing or difficult to impossible to implement.

Update-2 -用例(父级和子级指的是过程):

Update-2 - The use case (parent and children refer to process(es)):

我有一个应用程序,使用父母来管理一整群孩子,这依赖于父母的管理工具.为了完成其工作,父母需要依靠孩子的解雇通知,这是通过接收相关的SIGCHLD信号来完成的.

I have an app using a parent to manage a whole bunch of children, which rely on the parent's managment facility. To do its job the parent relies on being notified by a child's termination, which is done via receiving the related SIGCHLD signal.

如果父母由于某种意外(包括段节错)而死亡,我需要重新启动整个家庭",因为现在不可能触发孩子的解雇(这也可能是段节错).

If the parent itself dies due some accident (including segfaulting) I need to restart the whole "family", as it's impossible now to trigger something on a child's termination (which also might due to a segfault).

在这种情况下,我需要关闭所有子进程并重新启动整个系统.

In such a case I need to bring down all children and do a full system's restart.

避免这种情况的一种可能方法是,准备一个备用程序,该备用程序可以接管死去的父母的角色……-如果它可以再次接收步骤孩子的SIGCHLD信号!

A possible approach to avoid this situation, would be to have a spare-process in place which could take over the dead parent's role ... - if it could again receive the step children's SIGCHLD signals!

推荐答案

否,绝对不可能.没有一些令人讨厌的比赛条件,也无法实施.制作这些API的POSIX家伙永远不会创建具有固有竞争条件的东西,因此即使您不打扰,您的内核也不会很快得到它.

No, most definitely not possible. It couldn't be implemented either, without some nasty race conditions. The POSIX guys who make these APIs would never create something with an inherent race condition, so even if you're not bothered, your kernel's not getting it anytime soon.

一个问题是,pids被重用(它们是稀缺资源!),并且您也无法获得句柄或锁定;这只是一个数字.因此,例如,在代码中的某个地方,您有一个变量,您在其中放置了要重做的进程的pid.然后,您呼叫make_this_a_child_of_me(thepid).那会发生什么呢?同时,其他进程可能已经退出,并且thepid更改为引用了其他进程!哎呀.如果不对Unix处理进程的方式进行大的重组,就无法提供make_this_a_child_of_me API.

One problem is that pids get reused (they're a scarce resource!), and you can't get a handle or lock on one either; it's just a number. So, say, somewhere in your code, you have a variable where you put the pid of the process you want to reparent. Then you call make_this_a_child_of_me(thepid). What would happen then? In the meantime, the other process might have exited and thepid changed to refer to some other process! Oops. There can't be a way to provide a make_this_a_child_of_me API without large restructuring of the way unix handles processes.

请注意,对子pid进行wait处理的整个过程恰好是为了防止此问题:进程表中仍然存在僵尸进程,以防止其pid被重用.然后,父级可以通过其pid引用其子级,并确信该过程不会退出并且可以重用该子级pid.如果子项确实退出,则保留其pid,直到父项捕获SIGCHLD或等待它为止.一旦获取了该进程,它的pid就会立即被抢夺,以便其他程序在派生时开始使用,但是可以保证父进程已经知道了.

Note that the whole deal with waiting on child pids is precisely to prevent this problem: a zombie process still exists in the process table in order to prevent its pid being reused. The parent can then refer to its child by its pid, confident that the process isn't going to exit and have the child pid reused. If the child does exit, its pid is reserved until the parent catches SIGCHLD, or waits for it. Once the process is reaped, its pid is up for grabs immediately for other programs to start using when they fork, but the parent is guaranteed to already know about it.

响应更新:考虑一个更复杂的方案,在该方案中,流程将重新关联到其下一个祖先.显然,这并不是在每种情况下都可以做到的,因为您经常需要一种抛弃孩子的方式,以确保避免丧尸. init很好地履行了这一职责.因此,流程必须有某种方式来指定它打算采用或不采用其子孙(或更低子孙).这种设计的问题与第一种情况完全相同:您仍然获得比赛条件.

Response to update: consider a more complicated scheme, where processes are reparented to their next ancestor. Clearly, this can't be done in every case, because you often want a way of disowning a child, to ensure that you avoid zombies. init fulfills that role very well. So, there has to some way for a process to specify that it intends to either adopt, or not, its grandchildren (or lower). The problem with this design is exactly the same as the first situation: you still get race conditions.

如果再次由pid完成,则祖父母会将自己置于竞争状态:只有父代才能获得pid,因此只有父代才真正知道pid伴随哪个进程.由于祖父母无法获得收入,因此无法确定孙子流程与它打算采用的(或放弃,取决于假设的API的工作方式)没有改变.请记住,在一台负载很重的计算机上,没有什么可以阻止进程在几分钟内从CPU上退出,并且整个负载在那时可能已经改变了!不理想,但是POSIX必须考虑到这一点.

If it's done by pid again, then the grandparent exposes itself to a race condition: only the parent is able to reap a pid, so only the parent really knows which process a pid goes with. Because the grandparent can't reap, it can't be sure that the grandchild process hasn't changed from the one it intended to adopt (or disown, depending on how the hypothetical API would work). Remember, on a heavily-loaded machine, there's nothing stopping a process from being taken off the CPU for minutes, and a whole load could have changed in that time! Not ideal, but POSIX's got to account for it.

最后,然后假设pid不能使用该API,而通常只是说将所有孙子发送给我"或将他们发送给init".如果在生成子进程之后调用它,那么您将像以前一样获得竞争条件.如果以前调用过它,那么整个事情就没用了:您应该能够对应用程序进行一些重组,以获得相同的性能.也就是说,如果您在开始产生子进程之前就知道应该由谁作为父进程,那么为什么不能一开始就以正确的方式创建它们呢?管道和IPC确实能够完成所有必需的工作.

Finally, suppose then that this API doesn't work by pid, but just generally says, "send all grandchildren to me" or "send them to init". If it's called after the child processes are spawned, then you get race conditions just as before. If it's called before, then the whole thing's useless: you should be able to restructure your application a little bit to get the same behaviour. That is, if you know before you start spawning child processes who should be the parent of whom, why can't you just go ahead and create them the right way round in the first place? Pipes and IPC really are able to do all the required work.

这篇关于是否可以采用流程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆