简体   繁体   中英

Using PHP's posix_kill() in linux causing strange behaviour

I am creating a web page which will be used to monitor and control some custom C programs. I've created a page which will start/stop a C program 'launcher' (nice generic name) which then forks and creates a number of child processes. The starting works fine - exec("cd launcher_dir; nohup ./launcher > outfile 2>&1 &");

The stopping is where there's a problem. After clicking the stop button one of two things happens at random. Either there is a browser error page (101 Connection Reset or 324 Empty Response) or the page is loaded twice, but you only see it the second time. The reason I know it loads twice is because of debugging messages in the code. In both cases the launcher process is killed (sent SIGTERM). But if the page loads twice, on the first time it kills launcher (nothing loads on the page for this part) and the second time it checks and finds that no launcher process is running and displays a message: "Launcher is not running".

I am writing debug messages into a file and found that the reload occurs at a somewhat variable line in the php code (sometimes a certain debug message will print, other times it won't.) Also, php error reporting is set to ALL and no errors are given.

Launcher catches SIGTERM, sends SIGTERM to it's child processes in turn, and then calls exit(0).

Interestingly if SIGKILL is used to kill launcher, the php works fine and as expected, however this doesn't allow launcher to shut down nicely. What could be happening here?

Here is the relevant php code:

function stop_launcher(){
    $pid = get_launcher_pid(); // Definitely returns the correct pid
    debug_message("stop_launcher called, pid = ".$pid);
    if ($pid == "") {
        // If no 'connection reset' error occurs this is displayed
        // after first executing the else branch. Why is the php being run twice?
        print "Launcher doesn't seem to be running.. <br />";
        exit;
    } else {
        debug_message("killing");
        posix_kill(intval($pid), 15); //SIGTERM
        debug_message("kill finished"); // Sometimes this message is written, sometimes                      not
        if (ps_exists($pid)) { // Definitely works. This never gets displayed
            print "Shutdown failed. Try again</br>";
            exit;
        } 
    }
}

function debug_message($message){
    $fh = fopen(".debug", 'a') or die("can't open file");
    fwrite($fh, date("-r").":  ".$message."\n");
    fclose($fh);
}

Any suggestions are appreciated!

It turns out that this was one of those bugs that makes you feel stupid! The launcher program was accidentally killing it's process group...

Launcher is the shell. Some shells will send SIGTERM to their children if they receive SIGTERM. Changing "nohup" to "exec nohup" should get rid of the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM