杀死一个以popen开始的进程

Sop*_*ert 22 c multithreading kill popen

打开管道到进程后popen,有没有办法杀死已经启动的进程?(使用pclose不是我想要的,因为它将等待进程完成,但我需要杀死它.)

sla*_*acy 26

不要使用popen(),并编写自己喜欢的包装器.

fork()是相当简单的,然后使用dup2()替换stdin和stdout,然后在你的孩子上调用exec().

这样,你的父母将拥有确切的子PID,你可以使用kill().

Google搜索"popen2()实现"以获取有关如何实现popen()正在执行的示例代码.它只有十几条线.从dzone.com获取我们可以看到一个如下所示的示例:

#define READ 0
#define WRITE 1

pid_t
popen2(const char *command, int *infp, int *outfp)
{
    int p_stdin[2], p_stdout[2];
    pid_t pid;

    if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
        return -1;

    pid = fork();

    if (pid < 0)
        return pid;
    else if (pid == 0)
    {
        close(p_stdin[WRITE]);
        dup2(p_stdin[READ], READ);
        close(p_stdout[READ]);
        dup2(p_stdout[WRITE], WRITE);

        execl("/bin/sh", "sh", "-c", command, NULL);
        perror("execl");
        exit(1);
    }

    if (infp == NULL)
        close(p_stdin[WRITE]);
    else
        *infp = p_stdin[WRITE];

    if (outfp == NULL)
        close(p_stdout[READ]);
    else
        *outfp = p_stdout[READ];

    return pid;
}
Run Code Online (Sandbox Code Playgroud)

注意:似乎popen2()就像你想要的那样,但我的发行版似乎没有这种方法.

  • 以上需要"关闭(p_stdin [READ]);关闭(p_stdout [WRITE]);" 避免两个不需要的打开文件描述符延迟(这会阻止fgets()之类的调用检测到分叉子项已退出). (2认同)

che*_*web 5

这是popen2的改进版本(信用归功于Sergey L.).slacy发布的版本不会返回在popen2中创建的进程的PID,而是返回分配给的PID sh.

pid_t popen2(const char **command, int *infp, int *outfp)
{
    int p_stdin[2], p_stdout[2];
    pid_t pid;

    if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
        return -1;

    pid = fork();

    if (pid < 0)
        return pid;
    else if (pid == 0)
    {
        close(p_stdin[WRITE]);
        dup2(p_stdin[READ], READ);
        close(p_stdout[READ]);
        dup2(p_stdout[WRITE], WRITE);

        execvp(*command, command);
        perror("execvp");
        exit(1);
    }

    if (infp == NULL)
        close(p_stdin[WRITE]);
    else
        *infp = p_stdin[WRITE];

    if (outfp == NULL)
        close(p_stdout[READ]);
    else
        *outfp = p_stdout[READ];

    return pid;
}
Run Code Online (Sandbox Code Playgroud)

新版本将被调用

char *command[] = {"program", "arg1", "arg2", ..., NULL};
Run Code Online (Sandbox Code Playgroud)