i have the name of a long running process like ffmpeg (or more) and i want to kill it - or them - in php and without using the exec
Is that possible ? Its just like killall ffmpeg linux command .
You can kill process in safe way using the posix function "posix_kill".
Example:
// We assumes that 1223 PID is one ffmpeg process
posix_kill(1223, SIGHUP); // This send a polite termination signal to the process
posix_kill(1223, SIGINT); // This send a interrupt signal to the process
posix_kill(1223, SIGTERM); // This send the termination signal and tried to clean-up the process (Use it if SIGHUP and SIGINT fails)
posix_kill(1223, SIGKILL); // This send an unpolite signal to the kernel explaining that we want to kill the process ASAP and unconditionally and we don't care if we loss some data and the process is going to generate some memory leak (Use this as last option).
Now the problem is that you want to have the ffmpeg PID's, you can achieve that in a non-intrusive way reading the processes information from the "proc" filesystem.
Example that provides the process name:
/proc/1223/cmdline
In order to get the higher/maximum process number, you have to read the file /proc/sys/kernel/pid_max. Now you have to iterate across the process information in the "proc" filesystems until the pid_max is reached. You have have to check that process directory exists and that string returned from the /proc/xxxx/cmdline is contain the string "ffmpeg" or "libav" (Some linux distributions have renamed ffmpeg by libav or something like that).
Remember that in order to kill the ffmpeg processes the PHP script owner (Maybe Apache?) should be added to the same group that launch the ffmpeg processes.
Actually you can use linux commands via "exec" function, i don't know any other way. Check this out :
http://php.net/manual/en/function.exec.php
Related
How can I get PID of process started by Symfony?
The code bellow
$process = new \Symfony\Component\Process\Process('vlc');
$process->start();
return $process->getPid();
returns PID 1488. But there is no process (no vlc, no php) in system with same PID.
Edit
Presented code runs in app/console (Symfony\Component\Console\Command\Command)
Process forking
It's not unlikely for processes to spawn off their UI separately and letting the starter process end normally, i.e.
----> vlc (1488) ---> EOL
|
+--> vlc-ui (??) ---> Application
This behaviour is observable by running the application from the command line and checking whether the prompt returns almost immediately.
Hangup signal
Also note that when a parent process exits (your script), the child process may choose to also exit by listening to SIGHUP signals. If you're not doing so already, you could let your script "live" longer by adding a sleep() statement while you investigate.
Another approach that may work in some situations is doing it inversely like a script to grep parse a 'ps -A' containing the desired process (PHP e.g.) and rip off PID from the result. You don't have control on "who's who" on the result set but have control on "who's" actually running.
I am writing a php code for remote controlling some processes and devices that are connected to a linux pc. The codes are written in python. I can run the scripts and programs usnig php functions such as exec() or system() but I can not kill my processes.
I want to kill the python:
<?php
$PID = exec("pidof python");
echo $PID;
$kill = "kill " . $PID;
exec($kill);
?>
It returns the correct PID number but does not kill the process.
I also tried exec("kill #PIDnum"); but it does not work.
Any suggestions?
Thanks in advance
You can only kill processes from PHP that are owned by the userid running the web server on your system, which is usually set to a low-privilege account like "nobody", "www", web", etc.
It could work if the python were started from a PHP script. But otherwise, no.
A work around is to append lines to a file from PHP, the file to contain a list of the PIDs to be killed. This won't kill the processes, you will need to write a separate script to do that, in a language like bash or perl, python, etc. Have cron run that script as root, to periodically read the file, and kill the PIDs. But then, it won't be instantaneous. You could set up cron to run such a script every minute, though.
I'm starting my php script in the following way:
bash
cd 'path'
php -f 'scriptname'.php
There is no output while the php script is running.
After a time, the php script responds with:
Killed
My idea is that it reached the memory_limit: ini_set('memory_limit', '40960M');
Increasing the memory limit seemed to solve the problem, but it only increased the edge.
What exactly does that Killed phrase mean?
Your process is killed. There could be a multitude of reasons, but it's easy to discard some of the more obvious.
php limits: if you run into a php limit, you'll get an error in the logfile, and probably on the commandline as well. This normally does not print 'killed'
the session-is-ended-issues: if you still have your session, then your session is obvioiusly not ended, so disregard all the nohup and & stuff
If your server is starved for resources (no memory, no swap), the kernel might kill your process. This is probably what's happening.
In anycase: your process is getting send a signal that it should stop. Normally only a couple of 'things' can do this
your account (e.g. you kill the process)
an admin user (e.g. root)
the kernel when it is really needing your memory for itself.
maybe some automated process, for instance, if you live on a shared server and you take up more then your share of resources.
references: Who "Killed" my process and why?
You could be running out of memory in the PHP script. Here is how to reproduce that error:
I'm doing this example on Ubuntu 12.10 with PHP 5.3.10:
Create this PHP script called m.php and save it:
<?php
function repeat(){
repeat();
}
repeat();
?>
Run it:
el#apollo:~/foo$ php m.php
Killed
The program takes 100% CPU for about 15 seconds then stops. Look at dmesg | grep php and there are clues:
el#apollo:~/foo$ dmesg | grep php
[2387779.707894] Out of memory: Kill process 2114 (php) score 868 or
sacrifice child
So in my case, the PHP program printed "Killed" and halted because it ran out of memory due to an infinite loop.
Solutions:
Increase the amount of RAM available.
Break down the problem set into smaller chunks that operate sequentially.
Rewrite the program so it has a much smaller memory requirements.
Killed is what bash says when a process exits after a SIGKILL, it's not related to putty.
Terminated is what bash says when a process exits after a a SIGTERM.
You are not running into PHP limits, you may be running into a different problem, see:
Return code when OOM killer kills a process
http://en.wikipedia.org/wiki/Nohup
Try using nohup before your command.
nohup catches the hangup signal while the ampersand doesn't (except the shell is confgured that way or doesn't send SIGHUP at all).
Normally, when running a command using & and exiting the shell afterwards, the shell will terminate the sub-command with the hangup signal (kill -SIGHUP ). This can be prevented using nohup, as it catches the signal and ignores it so that it never reaches the actual application.
In case you're using bash, you can use the command shopt | grep hupon to find out whether your shell sends SIGHUP to its child processes or not. If it is off, processes won't be terminated, as it seems to be the case for you.
There are cases where nohup does not work, for example when the process you start reconnects the NOHUP signal.
nohup php -f 'yourscript'.php
If you are already taking care of php.ini settings related with script memory and timeout then may be its linux ssh connection which terminating in active session or some thing like that.
You can use 'nohup' linux command run a command immune to hangups
shell> nohup php -f 'scriptname'.php
Edit:- You can close your session by adding '&' at end of command:-
shell> nohup php -f 'scriptname'.php &> /dev/null &
'&' operater at end of any comand in linux move that command in background
Currently I have a parser.php which loads an xml file and inserts new data from the xml file into a mysql database. How would I go about refreshing this php file every 30 seconds so my mysql table always has fresh data? I think I could use short-polling to do this, but I'm guessing this is not the most efficient of options.
Thanks in advance
This is a non-PHP solution which will require you to have shell (SSH) access in order to run the script, however you can also run it through PHP with exec() if you want to. Shared hosting environments might present a challenge for this approach but as long as you can execute scripts under your user credentials you should have no problems running it.
First you will need to create a bash script with the following content and save it (I'll use the name parser.sh for the purpose of this example). You can then adjust the timeout in the sleep 30 line if you want to.
#!/bin/sh
while true
do
php parser.php
sleep 30
done
In order to run the script you'll need to give it execute permissions.
chmod +x parser.sh
Now you can use the nohup command with the ampersand (&) argument to ensure that the script will run in the background even when a termination signal is sent after, lets say, closing the shell (SSH). The ampersand is important!
nohup ./parser.sh &
Now you can use top or ps aux | grep parser to ensure that the script is running. As I already said before you can also use PHP exec() to start the process but shell is still the preferred and most reliable way to do this.
If you want to stop the background process which executes your script then you'll simply have to kill it. Just use ps aux | grep parser to find out the PID of the parser process (its in the second column to the left) and use it with the kill command.
kill 4183
You need to use a cronjob, but crons jobs runs every 1 minute or more.
Another way is to make a "daemon".
Very basic example:
<?php
while(true) {
// check if 30 seconds has passed.
// then execute some function...
};
?>
Then you need to execute this in your terminal:
$ php script.php &
This link should help.
Greatings!
I just wrote php daemon for my app and want to implement some output information generated on specified signal (SIGUSR1). I got signal handler in code
pcntl_signal(SIGUSR1, array($this, 'signal_status'));
and function handler prepared
protected function signal_status($signal_number)
{ printf("blah\n"); }
Everything work except one thing. When i send signal to my daemon (posix_kill($pid, SIGUSR1) or even simple kill -10 pid in bash) i got output in console that starts daemon.
Is it possible to get file descriptor of caller and not of the daemon? I wan't to send this data to specified output (for example after kill -10 PID) and not into FD of daemon.
I hope i wrote this clearly :)
Well, you can not, sending a signal is just setting up some operating system primitives, it has nothing to do with setting up a communication path between your daemon on one hand and the tool used to generate the signal on the other hand. The alternatives you have are either watching the console output of the daemon, or making the daemon dump status to a logfile and create some sort of utility to send the signal and print the logfile (and if you're going that way, why not throw out the logfile altogether and setup a periodical dump of your logging anyhow, since signals are not a polite way of doing inteprocess communiation.