父进程和子进程关系

Posted

技术标签:

【中文标题】父进程和子进程关系【英文标题】:Parent process and child process relation 【发布时间】:2010-07-26 07:44:48 【问题描述】:

我有打开子进程的父进程。只有当父进程不再运行时,我才需要执行一些功能。

知道父进程未运行的最佳方法是什么?因为它可能会被暴力终止,所以我不想做一些功能会在关闭事件时向我的子进程发送信号。

或者只是像这样寻找我的父进程:

在父母中做这个并将其传递给孩子Process.GetCurrentProcess().Id 并且在孩子每隔几毫秒检查一次这个

Process localById = Process.GetProcessById(1234);

有什么想法吗?建议..

【问题讨论】:

Erm... 通常它是一个父进程。除非你真的认识到你的过程的性别。干杯。 @AOI Karasu:大声笑,说得好,我冒昧地改变了它(如果性别很重要,请恢复我的改变,夜行者)。 我刚刚发布了一个.NET的子进程库childprocess.codeplex.com 【参考方案1】:

下面是一个简单的例子,如何使用Process.WaitForExit 来检查其 id 已在命令行中传递的父进程:

using System;
using System.Diagnostics;
using System.Threading;

class Program

    static AutoResetEvent _autoResetEvent;

    static void Main(string[] args)
    
        int parentProcessId = int.Parse(args[0]);

        _autoResetEvent = new AutoResetEvent(false);

        WaitCallback callback = delegate(object processId)  CheckProcess((int)processId); ;
        ThreadPool.QueueUserWorkItem(callback, parentProcessId);

        _autoResetEvent.WaitOne();
    

    static void CheckProcess(int processId)
    
        try
        
            Process process = Process.GetProcessById(processId);
            process.WaitForExit();
            Console.WriteLine("Process [0] exited.", processId);
        
        catch (ArgumentException)
        
            Console.WriteLine("Process [0] not running.", processId);
        

        _autoResetEvent.Set();
    

使用Process.Exited 事件可以这样完成:

using System;
using System.Diagnostics;
using System.Threading;

class Program

    static AutoResetEvent _autoResetEvent;

    static void Main(string[] args)
    
        int parentProcessId = int.Parse(args[0]);
        Process process = Process.GetProcessById(parentProcessId);
        process.EnableRaisingEvents = true;
        process.Exited += new EventHandler(process_Exited);

        _autoResetEvent = new AutoResetEvent(false);
        _autoResetEvent.WaitOne();
    

    static void process_Exited(object sender, EventArgs e)
    
        Console.WriteLine("Process exit event triggered.");
        _autoResetEvent.Set();
    

请注意,在这两个示例中,AutoResetEvent 的目的仅仅是为了防止您的主线程退出。在 Windows 窗体应用程序中,您不需要使用它,因为您的程序将处于消息循环中,并且只有在您关闭它时才会退出。

【讨论】:

我使用了 Process.Exited 示例。真的很感谢你的解释。【参考方案2】:

底层 Win32 进程句柄是可等待的,将在进程退出时发出信号。

在本机代码中:

DWORD res = WaitForSIngleObject(hProcess, INFINITE);
if (res == WAIT_OBJECT_0) 
  // process has exited.

在本机代码中,您需要为进程句柄创建 WaitHandle 的自定义子类型,或者使用 P/Invoke。 P/Invoke 的缺点是它更难组合(使用WaitForMultipleObjects 多次等待,因此您不会专门使用一个线程来等待一件事)。


感谢0xA3:只需使用Process.WaitForExit(有超时的过载以避免无限期等待,不要在你的UI线程上这样做)。

【讨论】:

对不起,我真的不想去 Native Code 。 @Night Walker:没必要,直接用Process.WaitForExit。最好放在单独的线程中。 但是我需要在子进程中等待父进程。不确定 Process.WaitForExit 如何提供帮助。 @NightWalker:父进程将父进程的 id 传递给子进程(例如在命令行上),或者对子进程使用 WMI 和 Win32_Process 请求并使用父进程 id 属性。一旦你有了父进程的 id,你就可以得到一个带有 Process.GetProcessById() 的 Process 实例。【参考方案3】:

当父进程启动子进程时,通过命令行参数将父进程ID传递给子进程。

然后在子进程上,使用Process.GetProcessById(int)获取父进程,使用Process.WaitForExit()。或者,您可以使用Process.Exited 事件在父进程退出时获得通知(记得将Process.EnableRaisingEvents 设置为true,否则不会引发该事件)。

【讨论】:

【参考方案4】:

我制作了一个子进程管理库,其中父进程和子进程通过双向 WCF 管道进行监控。如果子进程终止或父进程相互终止,则会收到通知。 还有一个调试器助手可用,它会自动将 VS 调试器附加到启动的子进程。

双向 WCF 通道是可扩展的,您可以处理进程启动和进程终止事件。

项目地点:

http://www.crawler-lib.net/child-processes

NuGet 包:

https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/

【讨论】:

以上是关于父进程和子进程关系的主要内容,如果未能解决你的问题,请参考以下文章

子进程怎么操作父进程中的变量

在 C++ 中父进程和子进程之间共享队列

父进程和子进程

父进程和子进程

swoole父进程和子进程之间通信的例子

swoole父进程和子进程之间通信的例子