8

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 use kill 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 like init always run on 1.

Is there any C api for that? and Also needed script for bash program.

10
  • @Christopher. I think you didn't get my question. Even pkill also do same thing
    – gangadhars
    May 22, 2014 at 12:16
  • 1
    @SGG There's no way to set a processes PID. That would cause all kinds of trouble. But you can use killall instead of kill which takes a program name instead of its PID. Or does your program name change that often?
    – mreithub
    May 22, 2014 at 12:18
  • @mreithub. If I have 2, 3 processes with same name, they all die
    – gangadhars
    May 22, 2014 at 12:21
  • 1
    @SGG Ok, use PID files then
    – mreithub
    May 22, 2014 at 12:22
  • 1
    Note 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
    – Basic
    May 22, 2014 at 18:35

5 Answers 5

13

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

12
  • +1 for the second half about checking where you are sending the signal.
    – user
    May 22, 2014 at 13:12
  • Why wouldn't you want to add a newline? Without it, you obtain a non-text file. Use printf instead of echo -n, not all implementations of echo support -n. Use = instead of ==, comm instead of cmd, $(cat< instead of $(< for portability (and quote your variables). May 22, 2014 at 19:04
  • The -n switch to echo 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. May 22, 2014 at 23:10
  • @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
    May 23, 2014 at 9:23
  • 2
    Note 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. May 23, 2014 at 10:39
6

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.

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

2
  • +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.
    – goldilocks
    May 22, 2014 at 12:49
  • @goldilocks Good point, updated answer to incorporate that.
    – user
    May 22, 2014 at 13:12
1

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.

0

System level daemon are assigned as per the sequence of start during boot time. I believe assigning a fixed pid to particular process is not possible because it is getting assigned by the Kernel as per the system load and other dependencies.

But using system call we may assign a fixed PID to the process. But no idea how can it be achieved.

3
  • i don't know any syscall for reserve a pid and i don't think this can be do it
    – c4f4t0r
    May 22, 2014 at 12:34
  • 1
    This 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.
    – user48669
    May 22, 2014 at 13:08
  • 1
    It is impossible to choose the PID of a process. The only exception is PID 1 which is assigned to the first process that is started when the system boots. May 22, 2014 at 23:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .