Run a process to particular/dedicated pid only
Solution 1
I don't think you can reserve or assign PIDs. However, you could start your process in a script like this:
myprocess &
echo "$!" > /tmp/myprocess.pid
This creates a "pid file", as some other people have referred to it. You can then fetch that in bash with, e.g., $(</tmp/myprocess.pid)
or $(cat /tmp/myprocess.pid)
.
Just beware when you do this that if the process died and the pid was recycled, you'll be signalling the wrong thing. You can check with:
pid=$(cat /tmp/myprocess.pid)
if [ "$(ps -o comm= -p "$pid")" = "myprocess" ]; then
...send your signal...
else echo "Myprocess is dead!"
fi
See comments if "$(ps -o comm= -p "$pid")"
looks strange to you. You may want to do a more vigorous validation if there is a chance of someone doing something devious with the content of /tmp/myprocess.pid
(which should not be writeable by other users!).
Solution 2
Fixing the pid is definitely the wrong solution to your problem, but note that with some versions of Linux, you can get a better chance to obtain the pid you'd like by writing a value to /proc/sys/kernel/ns_last_pid
:
echo 9999 | sudo tee /proc/sys/kernel/ns_last_pid; ps -C ps
9999
PID TTY TIME CMD
10000 pts/3 00:00:00 ps
That only works if the pid 10000 is not already in use (and there's been no pid or thread creation between the time you write to ns_last_pid and you spawn a process/thread).
Otherwise, you can always fork until you get the pid you like.
Solution 3
Something similar to what you want to do is normally done by the process early in its lifecycle writing out its own pid (which can be obtained through getpid(2)
) to a file with a known name. In general-use daemons the name of this file is often configurable, but in a special-use software you can probably get along with hardcoding it. (I strongly suggest at least using a macro for it, however.)
PID files are normally placed in /var/run or /run, but can be placed in other locations as well including /tmp. The "proper" location according to the Filesystem Hierarchy Standard is in /run, but /var/run also sees significant use (and on many modern systems is the same as /run) and /tmp don't require root privileges on startup (which system daemons very often have before they drop privileges).
That file can then be read through a variety of means to obtain the PID of the process in question, in order to send a signal to it process in question.
Solution 4
You can not set the PID, but you can set the PGID: create or join a process group. Then you can send signals to this dedicated process group.
I had the impression that the new systemd
init system has some automation on this part, which is superior to having the process to write its PID to a PID file and then using it for controlling it.
systemd
seems to switch to a "process group" (as I can understand this) before starting a controlled process, and then everything is in this group. So, you can control all the child processes by remembering the special "group".
If it functions like, this is superior to having the process to write out its PID, because you don't need to modify the program.
-
It might also be better then:
myprocess & echo $! > /tmp/myprocess.pid
because this approach captures all the children of that process, too.
I don't have a detailed documentation at hand to support my words, but here is the general idea of what systemd
needs from cgroups,a nd this seems to match my impression:
Control Groups are two things: (A) a way to hierarchally group and label processes, and (B) a way to then apply resource limits to these groups. systemd only requires the former (A), and not the latter (B). That means you can compile your kernel without any control group resource controllers (B) and systemd will work perfectly on it. However, if you in addition disable the grouping feature entirely (A) then systemd will loudly complain at boot and proceed only reluctantly with a big warning and in a limited functionality mode.
Related videos on Youtube
gangadhars
Updated on September 18, 2022Comments
-
gangadhars almost 2 years
I have a c program executable or shell script which I want to run very often. If I want to stop/pause or to notify something I will send signal to that process. So every time I have to check the
pid
of that process and I have to usekill
to send a signal.Every time I have to check pid and remembering that upto system shutdown, really bad. I want that process has to run on particular
pid
only likeinit
always run on 1.Is there any C api for that? and Also needed script for bash program.
-
Admin about 10 years@Christopher. I think you didn't get my question. Even
pkill
also do same thing -
Admin about 10 years@SGG There's no way to set a processes PID. That would cause all kinds of trouble. But you can use
killall
instead ofkill
which takes a program name instead of its PID. Or does your program name change that often? -
Admin about 10 years@mreithub. If I have 2, 3 processes with same name, they all die
-
Admin about 10 years@SGG Ok, use PID files then
-
Admin about 10 yearswhat do you mean by "PID files" @mreithub
-
Admin about 10 yearsCould you first please tell us which processes you want to control? I might give you better guidance then..
-
Admin about 10 yearsNote that just looking at the pid file is not enough to know if the process is running. If the power died, the file would be left behind so you should read the pid in the file and then check that a process with that pid is running. Of course, even this isn't fool-proof as another process may have started with the same pid... See Goldilock's answer for how to check it's the right process
-
Admin over 8 years
-
-
c4f4t0r about 10 yearsi don't know any syscall for reserve a pid and i don't think this can be do it
-
goldilocks about 10 years+1 Note
/var
and/run
require privileges to write to (which system daemons usually have, at least at start-up). If you don't want to do that,/tmp
, or some custom location, is fine. -
user131515 about 10 yearsThis answer does not seem to add anything to answers already posted. Maybe you could add some detail in order to make it better than other answers. As it stands, it seems to be just a rephrasing of previous answers.
-
user about 10 years@goldilocks Good point, updated answer to incorporate that.
-
user about 10 years+1 for the second half about checking where you are sending the signal.
-
Stéphane Chazelas about 10 yearsWhy wouldn't you want to add a newline? Without it, you obtain a non-text file. Use
printf
instead ofecho -n
, not all implementations ofecho
support-n
. Use=
instead of==
,comm
instead ofcmd
,$(cat<
instead of$(<
for portability (and quote your variables). -
Gilles 'SO- stop being evil' about 10 yearsThe
-n
switch toecho
is pointless here. It's perfectly fine to have a newline after the number, and in fact it's preferable because otherwise the pidfile wouldn't be a text file and some utilities might choke on it. -
goldilocks about 10 years@Gilles Dunno where I acquired this issue with newlines in pid files but after observing 1) they generally do have such and 2) I can't cause a problem with same, I've taken that bit out!
-
goldilocks about 10 years@StephaneChazelas Thx. Corrections made regarding POSIX-yness and obsolete sort keys, see also my preceding comment to Gilles. The only variables I did not quote were
$!
and$pid
inside"$(ps ....
, since if$pid
is empty there theif
will fail properly anyway. -
Stéphane Chazelas about 10 yearsLeaving a variable unquoted is the split+glob operator. You have no reason to invoke it here. Also bear in mind that the behaviour of the split part of that operator varies with the current value of
$IFS
. -
Stéphane Chazelas about 10 yearsNote that processes can change their names and another process can start with the same pid and name. Another option could be to record the output of
pid -o lstart= -p "$!"
(if on Linux) in the pid file and compare when it comes to killing the process. -
goldilocks about 10 years@StéphaneChazelas Are you saying that the
$pid
in"$(ps -o comm= -p $pid)"
should be quoted? How can I do that? If there's a way, this should be a short Q&A... If not, I could see performing some other validation first, in case someone tries to do something exploitative with the pid file content (in fact, such validation might be the best idea). -
Stéphane Chazelas about 10 yearsNot sure what you mean. I meant quoted as in
"$(ps -o comm= -p "$pid")"
andecho "$!"
(as the usual way to disable the split+glob operator) -
goldilocks about 10 years@StéphaneChazelas O_O ->
"$(ps -o comm= -p "$pid")"
I notice this works, but to me it looks like a concatenation with$pid
still unquoted. So (instead of concatenation) the shell first expands"$pid"
inside the rest of the expression? Anyway, I'll take your word on it and have applied the edits. -
mr.spuratic over 5 yearsSince (official) kernel v3.3. This method is used by CRIU for PID restoration in process checkpoint and restore, it's flock-able, and requires kernel option
CONFIG_CHECKPOINT_RESTORE
. See also the link added by Ciro to the question. -
Admin almost 2 years@StéphaneChazelas pid: command not found
-
Admin almost 2 years@TheTechRoboStandsforUkraine Based on the options (
-o lstart=
) I think it is safe to assume that should beps
, notpid
(in SC's second comment above).