我如何终止一个进程并在 C 中验证它不再是 运行?
How can I terminate a process and verify its not running anymore in 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, "%s\n", 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);
如果return值为0,则进程存在,如果-1则必须检查errno
。在 ESRCH
的情况下:
The target process or process group does not exist. Note that an existing process might be a zombie, a process that has terminated execution, but has not yet been wait(2)ed for.
要终止进程:
kill(pid, SIGTERM); // signal can be blocked, handled or ignored
或
kill(pid, SIGKILL); // signal cannot be blocked, handled or ignored
kill后,等待进程通过:
waitpid(pid, &status, 0);
If status
is not NULL
, wait()
and waitpid()
store status information in the int
to which it points. This integer can be inspected with the macros, described in the man page.
见
示例:
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, NULL, 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, NULL, 0);
/*if (res == -1) {
//not our child, or process does not exists
}*/
/*if (res > 0) {
//child successfully terminated
}*/
return res;
}
我想完全终止 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, "%s\n", 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);
如果return值为0,则进程存在,如果-1则必须检查errno
。在 ESRCH
的情况下:
The target process or process group does not exist. Note that an existing process might be a zombie, a process that has terminated execution, but has not yet been wait(2)ed for.
要终止进程:
kill(pid, SIGTERM); // signal can be blocked, handled or ignored
或
kill(pid, SIGKILL); // signal cannot be blocked, handled or ignored
kill后,等待进程通过:
waitpid(pid, &status, 0);
If
status
is notNULL
,wait()
andwaitpid()
store status information in theint
to which it points. This integer can be inspected with the macros, described in the man page.
见
示例:
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, NULL, 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, NULL, 0);
/*if (res == -1) {
//not our child, or process does not exists
}*/
/*if (res > 0) {
//child successfully terminated
}*/
return res;
}