【问题标题】:How can I get the processID created by popen?如何获取popen创建的processID?
【发布时间】:2013-09-29 04:14:09
【问题描述】:

我必须像 cmd 一样执行命令并返回结果。

我刚刚找到了满足这个要求的唯一方法。我使用popen函数执行命令并返回结果,然后使用pclose()函数关闭流和进程。

但是如果命令永远不会结束,例如“ping 8.8.8.8 –t”,我无法使用 pclose() 函数关闭进程。

如果我通过任务管理器杀死了 popen() 创建的子进程,pclose 函数可以正常工作。

如何获取 popen to kill 创建的 processID?

====================
并且:
如果我在windows中使用_popen(),我要怎么做才能得到PID?

【问题讨论】:

    标签: c++ popen pid pclose


    【解决方案1】:

    用'pipe + fork + dup2 + exec('/bin/bash', '-c', yourCommandHere)'自己包装一个popen函数

    【讨论】:

      【解决方案2】:

      popen() 是使用 execve() 或其他一些 exec 函数编写的。

      您要做的是 (1) 创建一对管道... pipe() 为您提供两个文件描述符。一个用于标准输入,另一个用于标准输出。然后你 fork() 并在子进程中执行 execve() 。在您调用 fork() 时,您将获得子进程。

      popen() 返回的文件是一个 FILE*,要从 pipe() 获取它,你必须执行 fdopen()。不太难。

      这是一项相当多的工作,但是如果您需要标识符...

      现在...在 MS-Windows 下,有点不同,你想使用 CreatePipe() 和 CreateProcess() 或类似的函数。但结果是相似的。

      【讨论】:

        【解决方案3】:

        使用

           ps -o user,pid,ppid,command -ax | grep <process name>
        

        获取所有子进程信息。实际上 popen() 使用 pipe() 机制来执行命令。参考手册页popen()

        在手册页中,

             The environment of the executed command  will  be  as  if  a
         child  process  were  created  within the popen() call using
         fork(2). If  the  application  is  standard-conforming  (see
         standards(5)), the child is invoked with the call:
        
         execl("/usr/xpg4/bin/sh", "sh", "-c",command, (char *)0);
        
         otherwise, the child is invoked with the call:
        
         execl("/usr/bin/sh", "sh", "-c",command, (char *)0);
        
         The pclose() function closes a stream opened by  popen()  by
         closing  the  pipe.  It  waits for the associated process to
         terminate and returns the termination status of the  process
         running  the command language interpreter. This is the value
         returned by waitpid(3C).
        

        它清楚地表明 popen 使用 pipe 和 fork 和 execl 来处理 popen() 函数。因此,您可以使用 ps 和 aux 来获取所有子进程信息。

        【讨论】:

        • 没有人,如果我的项目有很多同名的子进程会发生冲突。
        • 从 C/C++ 代码执行命令你必须使用 fork() 和 exec()
        猜你喜欢
        • 2011-03-01
        • 2014-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-26
        • 2020-08-14
        • 2018-12-21
        相关资源
        最近更新 更多