How can I do this task: if I kill a process, that process and other processes will all die ?
Kill the init process.
If you kill the parent process, child processes will remain and become a zombie.
There are many nice answers about process termination under Linux in general here : Best way to kill all child processes
Since I'm not too sure what you mean with that ambiguous question, I'm afraid this is the best answer I can give you.
Related
I'm working with parallel processing and rather than dealing with cvars and locks I've found it's much easier to run a few commands in a shell script in sequence to avoid race conditions in one place. The new problem is that one of these commands calls another program, which the OS has decided to put into a new process. I need to kill this process from the parent program, but the parent program only knows the pid of the parent (shell script), so this process keeps executing on its own.
Is there a way in bash to set a subprocess to die when the parent dies? I've tried to figure out how to execute it as a daemon because I read daemons exit when the parent dies, but it's tricky and I can't quite get it right. Thanks!
Found the problem, and this fixed it (except for some pesky messages that somehow cannot be redirected to /dev/null).
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
Is it possible to stop a PID from being reused?
For example if I run a job myjob in the background with myjob &, and get the PID using PID=$!, is it possible to prevent the linux system from re-using that PID until I have checked that the PID no longer exists (the process has finished)?
In other words I want to do something like:
myjob &
PID=$!
do_not_use_this_pid $PID
wait $PID
allow_use_of_this_pid $PID
The reasons for wanting to do this do not make much sense in the example given above, but consider launching multiple background jobs in series and then waiting for them all to finish.
Some programmer dude rightly points out that no 2 processes may share the same PID. That is correct, but not what I am asking here. I am asking for a method of preventing a PID from being re-used after a process has been launched with a particular PID. And then also a method of re-enabling its use later after I have finished using it to check whether my original process finished.
Since it has been asked for, here is a use case:
launch multiple background jobs
get PID's of background jobs
prevent PID's from being re-used by another process after background job terminates
check for PID's of "background jobs" - ie, to ensure background jobs finish
[note if disabled PID re-use for the PID's of the background jobs those PIDs could not be used by a new process which was launched after a background process terminated]*
re-enable PID of background jobs
repeat
*Further explanation:
Assume 10 jobs launched
Job 5 exits
New process started by another user, for example, they login to a tty
New process has same PID as Job 5!
Now our script checks for Job 5 termination, but sees PID in use by tty!
You can't "block" a PID from being reused by the kernel. However, I am inclined to think this isn't really a problem for you.
but consider launching multiple background jobs in series and then waiting for them all to finish.
A simple wait (without arguments) would wait for all the child processes to complete. So, you don't need to worry about the
PIDs being reused.
When you launch several background process, it's indeed possible that PIDs may be reused by other processes.
But it's not a problem because you can't wait on a process unless it's your child process.
Otherwise, checking whether one of the background jobs you started is completed by any means other than wait is always going to unreliable.
Unless you've retrieved the return value of the child process it will exist in the kernel. That also means that it's pid is bound to it and can't being re-used during that time.
Further suggestion to work around this - if you suspect that a PID assigned to one of your background jobs is reassigned, check it in ps to see if it still is your process with your executable and has PPID (parent PID) 1.
If you are afraid of reusing PID's, which won't happen if you wait as other answers explain, you can use
echo 4194303 > /proc/sys/kernel/pid_max
to decrease your fear ;-)
I try to kill process by using command "kill -9 pid", but can not succeed. Anybody know how could I kill such process and why I can't kill it ?
The process could be zombie? Its good to check process state using ps command as well if you have permission.
If your process is in an uninterruptable sleep (D) due to hanging in some hardware access, you indeed cannot terminate that process.
Here is another explanation.
Personally, I saw such D states for example when accessing files on a SD card or USB stick when there was a hardware problem. But there are many other scenarios where such a state might occur.
For example the bash pid is 3000, and I want to limit the child pid to be in the range [3001,3010].
I want this because I am writing a infinite while loop in bash, and the pid will explode.
while true;do
something;
sleep 5;
done;
Every loop spawned at least 3 child processes(true, something, sleep). So the pid whill grow at the speed of at least 3 per sec. After a time, ps aux will show an awkwardly big pid, I think it is not a good thing.
The PIDs don't "explode". They are recycled by the kernel. You can see the maximum PID number in /proc/sys/kernel/pid_max. Of course, you can modify this value, if you wish.
No, that is totally impossible, since the pid is assigned by the kernel when it is running the fork(2) syscall. A user-level application or library cannot change that. Indeed the kernel is at some time recycling pids, as answered by Alex.
You might do a big loop on fork and exit immediately the child process if its pid (with getpid) is unsuitable, but that approach is insane, since you might need to fork several thousands times before being lucky.
Perhaps namespaces(7) could be relevant.
There is no sane way to do that from user space, and no sane reason to want to.
If you are convinced that you have to solve this problem, and you have the sources to something, hack it to run an infinite loop with a sleep between iterations. Then you will stay in the same PID forever.
(Or slightly more off the wall, hack Bash so that sleep and something are built-ins, too. For the record, true is already a Bash built-in, so it will not actually spawn a subprocess.)
From what I gather, programs that run as pid 1 may need to take special precautions such as capturing certain signals.
It's not altogether clear how to correctly write a pid 1. I'd rather not use runit or supervisor in my case. For example, supervisor is written in python and if you install that, it'll result in a much larger container. I'm not a fan of runit.
Looking at the source code for runit is intersting but as usual, comments are virtually non-existent and don't explain what's being done for what reason.
There is a good discussion here:
When the process with pid 1 die for any reason, all other processes
are killed with KILL signal
When any process having children dies for any reason, its children are reparented to process with PID 1
Many signals which have default action of Term do not have one for PID 1.
The relevant part for your question:
you can’t stop process by sending SIGTERM or SIGINT, if process have not installed a signal handler