Linux 如何在 C++ 中杀死进程,只知道其名称的一部分

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11933969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:04:28  来源:igfitidea点击:

How to kill process in c++, knowing only part of its name

c++linuxunixprocesskill

提问by John_West

Some time ago I needed to write c++ code to kill some process. In my main program I run large CAE-system package with system("...") with different filename strings on input. CAE-software creates many processes, that contain in process name string filename). Some of the CAE-processes worktime> max_time, than I need to shut them down:

前段时间我需要编写 C++ 代码来杀死一些进程。在我的主程序中,我使用 system("...") 在输入时使用不同的文件名字符串运行大型 CAE 系统包。CAE 软件创建了许多进程,这些进程包含在进程名称字符串filename 中)。一些 CAE 进程worktime> max_time,比我需要关闭它们:

//filename contains part of CAE-process name
    string s="/bin/kill -9 `ps aux | grep "+filename+" | awk {'print '}`";
    system(s.c_str());

The output was:

输出是:

Usage:
  kill pid ...              Send SIGTERM to every process listed.
  kill signal pid ...       Send a signal to every process listed.
  kill -s signal pid ...    Send a signal to every process listed.
  kill -l                   List all signal names.
  kill -L                   List all signal names in a nice table.
  kill -l signal            Convert between signal numbers and names.

I tried to run with execvp, tried different ways running kill or pkill over bash script, calling system("name_of_script.sh"), where script contained kill -9 *filename*but the result was the same.
Using killand /bin/killgave the same output, bash -c kill...too.
Using killfrom my system(Ubuntu Natty) gnome-terminal:

我尝试使用 execvp 运行,尝试通过 bash 脚本运行 kill 或 pkill 的不同方式,调用 system("name_of_script.sh"),其中包含脚本kill -9 *filename*但结果相同。
使用kill和 也/bin/kill给出了相同的输出bash -c kill...
使用kill从我的系统(Ubuntu的纳蒂)GNOME终端

kill -9 `ps aux | grep filename | awk {'print '}`

shutdown all necessary processes! It works.

关闭所有必要的进程!它有效

When using pkill, as I could understand, we need full process name to kill it, but I have only part of name.

使用时pkill,据我所知,我们需要完整的进程名称来杀死它,但我只有部分名称。

I also tried to wrap computational process into a child thread using pthreads and stop it with pthread_cancel, but it doesn't work because of CAE-system process doesn't receive signals (I think, trapping them), the only way is SIGTERM.
Killing child-thread-"wrap" with pthread_kill also kills the parent (my main program).

我还尝试使用 pthreads 将计算过程包装到子线程中并使用 pthread_cancel 停止它,但它不起作用,因为 CAE 系统进程不接收信号(我认为,捕获它们),唯一的方法是 SIGTERM。
使用 pthread_kill 杀死子线程“包装”也会杀死父线程(我的主程序)。

I don't know CAE-process pids to call kill from signals.h
Closing main program do not stop CAE-processes (and the do not have -Z flag, so are they aren't my program process childs??)

我不知道 CAE 进程 pids从信号中调用 kill.h
关闭主程序不会停止 CAE 进程(并且没有 -Z 标志,所以它们不是我的程序进程子进程吗??)

How can I close CAE-processes, that run > MAXTIME from my main program?

如何关闭从主程序运行 > MAXTIME 的 CAE 进程?



The problem was that I was running main program via debugger (gdb) in QtCreator. Without QtCreator shell-script runs with arguments the right way, though arguments are passed correctly both ways.

问题是我在 QtCreator 中通过调试器(gdb)运行主程序。没有 QtCreator,shell 脚本以正确的方式运行参数,尽管参数在两种方式都正确传递。



Also I have to clear some CAE processes, that don't have filename in cmdline, but that are parents or children of this process. In shell-script you can use:

此外,我必须清除一些 CAE 进程,这些进程在 cmdline 中没有文件名,但它们是此进程的父进程或子进程。在 shell 脚本中,您可以使用:

cat /proc/"$P"/status | grep PPid | grep -o "[0-9]*"

where $Pis a variable with pid of killed process. Here are several methodsto kill all child processes.

where$P是一个带有被杀死进程的 pid 的变量。 这里有几种杀死所有子进程的方法。

I'll write smth. similar in C++ that will scan /proc/xxxx/statustill PPid= ppid_of_my main_program and cut that branch.

我会写的。在 C++ 中类似,它将扫描/proc/xxxx/status直到PPid= ppid_of_my main_program 并切断该分支。

采纳答案by Rafael Baptista

You don't have to open a shell to kill a process. Just use the "kill" function:

您不必打开外壳来终止进程。只需使用“kill”功能:

#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int sig);

http://linux.die.net/man/2/kill

http://linux.die.net/man/2/kill

To find a process to kill read the following directory:

要查找要杀死的进程,请阅读以下目录:

/proc/####/cmdline

/proc/####/cmdline

Where #### is the number of any running process id. So the code roughly would be to read the /proc directory and list out all the numerical directories, these are the current running processes, and you find the name of the command that spawned that process in the "cmdline" file in that directory. You can then use a regular expression, or a string comparison to identify processes to kill.

其中#### 是任何正在运行的进程 ID 的编号。因此,代码大致是读取 /proc 目录并列出所有数字目录,这些是当前正在运行的进程,您可以在该目录的“cmdline”文件中找到生成该进程的命令的名称。然后,您可以使用正则表达式或字符串比较来识别要终止的进程。

回答by jlliagre

This should just work assuming filename isn't too much exotic or contains a regular expression pattern:

这应该只是假设文件名不是太奇特或包含正则表达式模式:

string s="pkill -9 -f "+filename";
system(s.c_str());

As a side note, -9is a last resort signal, not something you should start with. I would thus recommend the less brutal:

附带说明一下,这-9是最后的手段信号,而不是您应该开始的信号。因此,我会推荐不那么残酷的:

string s="pkill -f "+filename"+";sleep 2; pkill -9 -f "+filename;
system(s.c_str());