4

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:

//filename contains part of CAE-process name
    string s="/bin/kill -9 `ps aux | grep "+filename+" | awk {'print $2'}`";
    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 kill and /bin/kill gave the same output, bash -c kill... too.
Using kill from my system (Ubuntu Natty) gnome-terminal:

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

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.

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).

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??)

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


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.


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:

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

where $P is a variable with pid of killed process. Here are several methods to kill all child processes.

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

Community
  • 1
  • 1
John_West
  • 2,239
  • 4
  • 24
  • 44
  • 1
    Are these processes ones that you're creating from your program? It would be much easier to remember the pid and kill them that way. – Wug Aug 13 '12 at 12:07
  • 1
    Are you sure you really want to do this in C++ instead of shell? – pmr Aug 13 '12 at 12:08
  • I call CAE with system("launcher.sh filename"); Filename differs each time. Oh, I can only take launcher's pid, that finishes in two seconds and creates CAE processes. – John_West Aug 13 '12 at 12:09
  • Shell is welcome too. I can call script using system("script.sh"); where scripts.sh contains #/bin/bash kill -9 \`ps aux | grep $1 | awk {'print $2'}\` doesn't run (the same error: usage: kill...) – John_West Aug 13 '12 at 12:11
  • system("script.sh filename") of course. – John_West Aug 13 '12 at 12:22
  • If you temporarily replace `kill` with `echo ARGS: `, do you see a list of process IDs? – aschepler Aug 13 '12 at 12:28
  • Yes! Both ways - via debugger too. $0 contains script name, $1 - string for search to be killed. – John_West Aug 13 '12 at 12:37

2 Answers2

15

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

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

int kill(pid_t pid, int sig);

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

To find a process to kill read the following directory:

/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.

Rafael Baptista
  • 11,181
  • 5
  • 39
  • 59
  • 2
    For reading `/proc/xxx/cmdline` check out my answer here: http://stackoverflow.com/questions/6898337/c-determine-programmatically-if-a-program-is-running/6898456#6898456 – John Ledbetter Aug 13 '12 at 12:59
  • Thanks! /proc scanning is a good thing! Though problem, as I understood, was that processes was started at gdb space. – John_West Aug 13 '12 at 13:20
  • @Rafael Baptista can you suggest how to send a signal from c/c++ code with the executable file name instead of PID. – PARTHA SARATHI Ravi Jul 04 '22 at 09:12
  • You need to look up the PID using the executable file name - but it isn't foolproof because there may be more than one process running with that executable. Iterate over all running process in /proc like in this question https://stackoverflow.com/questions/63372288 and then see if the the contents of the "cmdline" file match your executable. – Rafael Baptista Jul 08 '22 at 00:20
1

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

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

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

string s="pkill -f "+filename+";sleep 2; pkill -9 -f "+filename;
system(s.c_str());
Community
  • 1
  • 1
jlliagre
  • 29,783
  • 6
  • 61
  • 72