微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何终止进程并验证它不再在 C 中运行?

如何解决如何终止进程并验证它不再在 C 中运行?

我想在 Linux C89 上完全终止一个进程。

流程是:检查它是否已经死亡,如果没有,使用sigterm让它平静地死去,等待10秒直到它死去。如果它仍然活着 - SIGKILL 它。

int TerminateProcessIMP(pid_t process_to_kill)
{    
    assert(process_to_kill);
    
    /*---------------------------------------------------------*/
    /*  check if process is already does not exist */
    if (!IsProcessAliveIMP(process_to_kill))
    {
        return (SUCCESS);
    }
    /*---------------------------------------------------------*/
    /*  terminate process_to_kill   */
    if (kill(process_to_kill,SIGTERM))
    {
        fprintf(stderr,"%s\n",strerror(errno));
    }
    
    if (!IsProcessAliveIMP(process_to_kill))
    {
        return (SUCCESS);
    }
    
    /*---------------------------------------------------------*/
    /*  if its still alive,SIGKILL it */
    if (kill(process_to_kill,SIGKILL))
    {
        fprintf(stderr,strerror(errno));
    }
    
    if (!IsProcessAliveIMP(process_to_kill))
    {
        return (SUCCESS);
    }
    /*---------------------------------------------------------*/

    return (FAILURE);
}
/******************************************************************************/
int IsProcessAliveIMP(pid_t process_to_check)
{
    time_t start_time = 0;
    time_t end_time = 0;
    time_t time_to_wait = 10; /* in seconds */
    
    assert(process_to_check);
    
    start_time = time(0);
    end_time = start_time + time_to_wait;
    
    /*  give it time to be terminated because maybe it frees memory meanwhile */
    while (0 != kill(process_to_check,0) && time(0) < end_time)
    {}
    
    /*  check if it still exists */
    if (0 == kill(process_to_check,0))
    {
        return (0);
    }
    
    /* the process is still alive */
    return (1);
}

你怎么看?

现在,它不起作用,也不会终止进程。

它试图终止进程,但没有这样做。我不明白为什么。

谢谢。

解决方法

你在做不必要的事情。

检查进程是否存在:

kill(pid,0);

如果返回值为0,则进程存在,如果为-1,则必须检查errno。在 ESRCH 的情况下:

目标进程或进程组不存在。请注意,现有进程可能是僵尸进程,即已终止执行但尚未等待 (2) 的进程。


终止进程:

kill(pid,SIGTERM); // signal can be blocked,handled or ignored

kill(pid,SIGKILL); // signal cannot be blocked,handled or ignored

杀死后,您必须通过以下方式等待该过程:

waitpid(pid,&status,0);

如果 status 不是 NULLwait()waitpid() 将状态信息存储在它指向的 int 中。可以使用手册页中描述的宏检查此整数。


man kill
man waitpid


示例:

int TerminateProcessIMP(pid_t pid)
{
    //check if process exists
    int res = kill(pid,0);
    
    if ((res == -1) && (errno != ESRCH)) {
        //error: either EINVAL or EPERM
        //ESRCH: an existing process might be a zombie
        return -1;
    }
    
    if (res == 0) { //process exists
        
        //ask politely to terminate
        
        if (kill(pid,SIGTERM) == -1) {
            //error: unable to send a signal to the process
            return -1;
        }
        
        //let us see if the child complied to our request
        res = waitpid(pid,NULL,WNOHANG | WUNTRACED | WCONTINUED);
        
        if (res == -1) {
            //most likely not our child (errno == ECHILD)
            //but the process could follow our request and still terminate
            //if you want to be sure goto SIGKILL below
            //or return
        } else if (res == 0) {
           //our child,but at this point the child has not terminated yet 
           //(maybe it will never)
           //either continue to wait or goto SIGKILL below
        } else {
           //child complied to our request and terminated in time
           //res contains the id of the child (res == pid)
           return res;
        }

        //--- or ---

        /* do {
            res = waitpid(pid,WNOHANG | WUNTRACED | WCONTINUED);
            //because of WNOHANG
            sleep(1);
            //your timeout method goes here
        } while (!res);

        if (res == -1) { //same as above }
        if (res  >  0) { return res;     } */
        
    }
    
    //at this point,the process either does not exists (maybe zombie),//is not our child or refused our request (SIGTERM)
    
    //send a SIGKILL signal to the process
    kill(pid,SIGKILL);
    
    //wait for the process to terminate
    res = waitpid(pid,0);
    
    /*if (res == -1) {
        //not our child,or process does not exists
    }*/
    
    /*if (res > 0) {
        //child successfully terminated
    }*/
    
    return res;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。