从父级分离子进程

时间:2017-10-07 14:44:51

标签: unix posix child-process

当从父级分叉的子进程死亡时,它仍然存在一定程度并且处于僵尸状态,直到从wait()调用中获取。

是否可以分离这个父子关系并让孩子自动获得收入?也许可以将孩子从初学者那里孤儿或其他东西?

可能的用例:在一个长期存在的程序中创建大量的“即发即弃”流程,而不是"持有"更多的僵尸PID无法通过操作系统回收。

3 个答案:

答案 0 :(得分:5)

the POSIX _exit() documentation

  

如果调用进程的父进程已设置了它   SA_NOCLDWAIT标记或已将SIGCHLD信号的操作设置为   SIG_IGN

     
      
  • 过程'状态信息(见状态信息),如果有的话,应该被丢弃。

  •   
  • 呼叫过程的生命周期应立即结束。如果设置了SA_NOCLDWAIT,则是SIGCHLD是实现定义的   信号被发送到父进程。

  •   
  • 如果调用进程的父进程中的某个线程在wait()waitpid()waitid()中被阻止,并且父进程已   在这组等待的孩子中没有剩余的子进程   wait()waitid()waitpid()功能将失败并设置errno   到[ECHILD]。

  •   
     

否则:

     
      
  • 应生成状态信息(参见状态信息)。

  •   
  • 调用流程应转换为僵尸流程。其状态信息应提供给父进程   直到过程'终身结束。

  •   
  • ...

  •   

简而言之,为了防止子进程成为僵尸进程,最简单的方法是调用sigignore( SIGCHLD );

<强>更新

这确实会影响等待任何子进程的能力,这可能是不可取的。 setsid() library function允许进程与其父进程取消关联:

pid_t child = fork();
if ( ( pid_t ) 0 == child )
{
    int rc = setsid();

    rc = execv(...);
}
else ...

解除关联的子进程不会创建僵尸,也不会将SIGCHLD发送到我安装的Solaris 11.2实例上的父进程。

这是&#34;“即发即忘”的缩写守护程序。子进程,只执行必要的操作以防止创建僵尸或将SIGCHLD发送到父进程。有关更全面的守护程序,请参阅Linux daemonize

答案 1 :(得分:1)

忽略SIGCHLD或为SIGCHLD安装一个sighandler并启用SA_NOCLDWAIT标志,可以防止所有子级变成僵尸(/可以wait使用)。

要为一个孩子做这件事,您可以使用不带clone()标志的Linux的SIGCHLD,也可以加倍fork(或vfork,如果您知道如何安全地这样做)。然后,孩子可以立即_exit(0) wait并由其父母init抚养,孙子可以继续从事实际工作(就像您所说的ps一样)。

(双叉的轻微扩展将是完全妖魔化,子代或孙子会调用setid来创建新会话,新进程组并与控制终端分离。Setsid单独不会阻止孩子成为僵尸,只会在默认设置中将ps中的僵尸隐藏在window.onload = function() { var chart = new CanvasJS.Chart("chartContainer", { toolTip: { borderThickness: 3 }, data: [ { indexLabelFontColor: 'white', indexLabel: "{label} ", indexLabelPlacement: "inside", toolTipContent: "<b>{label}</b><br>{text}<br/>", type: "pie", cursor:"pointer", dataPoints: [ { label: "Collaborate", y: 16, link:"http://google.com/", text:'gg' }, { label: "Discuss", y: 16, link:"http://bing.com/", text:'gg'}, { label: "Practice", y: 16, link:"http://search.yahoo.com/", text:'gg' }, { label: "Investigate", y: 16, link:"http://www.duckduckgo.com/", text:'gg' }, { label: "Acquire Knowledge", y: 16, link:"http://www.duckduckgo.com/", text:'gg' }, { label: "Produce", y: 16, link: "http://www.dogpile.com/", text:'gg' } ] } ] }); chart.options.data[0].click = function(e){ var dataSeries = e.dataSeries; var dataPoint = e.dataPoint; var dataPointIndex = e.dataPointIndex; if(!dataPoint.exploded) window.open(dataPoint.link,'_blank'); for(var i = 0; i < dataSeries.dataPoints.length; i++){ if(i === dataPointIndex){ continue; } dataSeries.dataPoints[i].exploded = false; } }; chart.render(); } 中,其中traffic_id|date|start_time|session_id|page|platform|page_views|revenue|segment_id|customer_id 303|1/1/2017|05:23:33|123457080|homepage|mobile|581|37.40|1|310559 仅显示当前终端控制会话中的进程。)

答案 2 :(得分:-1)

从Python 3.2开始,您可以使用subprocess.Popen()并传递start_new_session = True来完成此操作。

文档状态:

如果start_new_session为true,则将在子进程执行之前在子进程中进行setsid()系统调用。 (仅适用于POSIX)

https://docs.python.org/3/library/subprocess.html#subprocess.Popen

请注意,如后续评论中所述,这不允许一个人“在孩子的一生中的任意阶段从父母那里做这件事”。