3

I'm using php processes to send emails in the background and I'm trying to find a way to auto-resume in case the server ever goes down or something happens to the script to make it stop.

My logic is: if the send session is still running but hasn't sent a new email in X time, kill the process if already running and start a new process.

Now, my problem lies with the "kill process if already running" part. How can I be sure this process with this PID is the same process I started for the send session? I can't check the name because I'm going to have several of them running at the same time. I don't want to kill a random process or another send process.

So the problem is: how can I uniquely identify a process running on linux? Or how can I mark it in some way to make it unique? Is there a way to maybe check its parameters from outside?

Bogdan
  • 1,779
  • 6
  • 21
  • 50
  • You can create a PID file like most other software does and chick this file. A db stored value is also usable. If it is a console run PHP script, you can store your PID with getmypid() and use this PID to kill if necessary. – ToBe Jan 30 '14 at 13:42
  • I already have the PID of the process stored in the database. I need some way to make sure this is without a doubt the right process for the send session. – Bogdan Jan 30 '14 at 13:43
  • If you script was run as console PHP script, you CAN be sure. – ToBe Jan 30 '14 at 13:44
  • Even after a server shutdown? The scripts can run for days, even weeks; I want to eliminate the chance that a server shutdown causes the PID to be reassigned to some other process. – Bogdan Jan 30 '14 at 13:49
  • Ok, I didnt expect a server shutdown... Guess not. I doubt there is a way to get a persistant unique process id. Oh, but BTW, there is a maximum execution time in PHP. Maybe use this as a better way to prevent zombie processes? – ToBe Jan 30 '14 at 13:50
  • That's why I was looking for something apart from PID. – Bogdan Jan 30 '14 at 13:52
  • You can send email from PHP using SMTP. See [this](http://stackoverflow.com/q/14456673/841108). Don't need to put some process in background. You could have a local SMTP mail transfer agent. – Basile Starynkevitch Jan 30 '14 at 13:55
  • @BasileStarynkevitch I'm already using SMTP. This is for sending a whole bunch of emails one after another as part of a newsletter function (up to hundreds of thousands of emails in one campaign). – Bogdan Jan 30 '14 at 14:50

2 Answers2

0

unlike what was suggested in comments, PIDs are NOT sufficient to uniquely identify processes, due to PID reuse (exacerbated by the limited number of unique PIDs, usually 32768 ). however, if you combine the pid AND the start time of the process, that should be sufficiently unique in practice. and the start time kernel tick is recorded in /proc/$pid/stat , with that in mind, you can make an unique-ish hash like this:

function unique_hash_pid(int $pid): string {
    return $pid . ':' . (explode ( ' ', file_get_contents ( '/proc/' . $pid . '/stat' ) ) [21]);
}

(i imagine the chance of a process starting, then getting uniquely identified by PHP, then exiting, then another process starting, and getting reassigned to the exact same pid, all in under a single kernel tick, is... practically zero. thus this hash should be unique. if someone does a lab test for this though, please let me know!)

however, know that this function does not consider restarts, and may produce the same hash for 2 completely different processes between restarts (if the same pid is started on the exact same kernel tick between 2 restarts. i imagine this is rather common for startup scripts)

hanshenrik
  • 15,263
  • 3
  • 28
  • 61
0

Pids do not uniquely identify a process, because of pid reuse. Out of the same reason the tuple (pid, command) cannot be used as an identifier. Neither is the tuple (pid, process start time) useful, because the process start time seems to be fragile and change for example because of NTP time reset (and other reasons?), and something that changes cannot be used as an identifier.

However, to really uniquely identify a process, we can make them distinguishable ourselves. For example, in PHP the function cli_set_process_title [1] can be used to change the process title. If we prepend a random number to the process title and store this nonce together with the pid, we can later differentiate between processes that reuse the same pid but have a different nonce, and processes that have the same pid and the same nonce in the title.

(Actually the nonce is now sufficient to identify the process, and the pid is not necessary, but it is still useful to store the pid so we do not have to search for the process in the process list.)

[1] https://www.php.net/manual/en/function.cli-set-process-title.php

drcicero
  • 111
  • 1
  • 6