Executing functions parallelly in PHP

12,698

Solution 1

On Unix platforms you can enable the PCNTL functions, and use pcntl_fork to fork the process and run your jobs in child processes.

Something like:

function fast_call_user_func_array($func, $args) {
  if (pcntl_fork() == 0) {
    call_user_func_array($func, $args);
  }
}

Once you call pcntl_fork, two processes will execute your code from the same position. The parent process will get a PID returned from pcntl_fork, while the child process will get 0. (If there's an error the parent process will return -1, which is worth checking for in production code).

Solution 2

You can check out PHP Process Control:

http://us.php.net/manual/en/intro.pcntl.php

Note: This is not threading, but the handling of separate processes. There is more overhead attached.

Solution 3

Wouldn't it solve your problem to fork, keeping the parent process free for other connections & actions? See http://www.php.net/pcntl_fork. If you need an answer back you could possibly listen to a socket in the parent, and write with the child. A simple while(true) loop with a read could possibly do, and probably you already have that basic functionality if you run a permanent TCP server. Another option would be to keep track of your childprocess-ids, keep a accessable store somewhere (file/database/memcached etc), with a pcnt_wait in the main process with a WNOHANG to check which process has exited, and retrieve the data from the store.

Solution 4

You can do some threading in PHP if you use the method pcntl_fork.

http://ca.php.net/manual/en/function.pcntl-fork.php

I have never use this myself, but the are some good example of how to use it on php.net.

Share:
12,698
binaryLV
Author by

binaryLV

Updated on July 18, 2022

Comments

  • binaryLV
    binaryLV almost 2 years

    Can PHP call a function and don't wait for it to return? So something like this:

    function callback($pause, $arg) {
        sleep($pause);
        echo $arg, "\n";
    }
    
    header('Content-Type: text/plain');
    fast_call_user_func_array('callback', array(3, 'three'));
    fast_call_user_func_array('callback', array(2, 'two'));
    fast_call_user_func_array('callback', array(1, 'one'));
    

    would output

    one (after 1 second)
    two (after 2 seconds)
    three (after 3 seconds)
    

    rather than

    three (after 3 seconds)
    two (after 3 + 2 = 5 seconds)
    one (after 3 + 2 + 1 = 6 seconds)
    

    Main script is intended to be run as a permanent process (TCP server). callback() function would receive data from client, execute external PHP script and then do something based on other arguments that are passed to callback(). The problem is that main script must not wait for external PHP script to finish. Result of external script is important, so exec('php -f file.php &') is not an option.


    Edit: Many have recommended to take a look at PCNTL, so it seems that such functionality can be achieved. PCNTL is not available in Windows, and I don't have an access to a Linux machine right now, so I can't test it, but if so many people have advised it, then it should do the trick :)

    Thanks, everyone!

  • ircmaxell
    ircmaxell almost 14 years
    That's not threading. Fork()ing creates a new process as a copy of the current one. You cannot return values or share variables from one process to another (you need to use some form of IPC: sockets, shared memory, fifo files, etc).
  • ircmaxell
    ircmaxell almost 14 years
    I don't know that I'd say there's more overhead attached in general. On Windows, sure, fork()ing is expensive. But on Linux, it's actually very cheap. The "overhead" you speak of could be seen as needing to deal with IPC (you can't just return a value from one process to another, so you do need some code to handle communication)... If your processes are very independent, forking can be the most efficient way to handle them...
  • ircmaxell
    ircmaxell almost 14 years
    Again, fork() and threads are two completely different things. PHP has no concept of threads. Fork() takes a single running php process and "copies" it on a second process (copying all variables etc). There's no way to return the value from one process to another without some form of IPC. It's VERY different from threading...
  • webbiedave
    webbiedave almost 14 years
    Processes have their own state and memory space. Threads do not. That's the overhead I'm speaking of.
  • Chris
    Chris almost 14 years
    @ircmaxell - right. I guess I was being a bit loose with my terminology. s/thread/process/g :)
  • ircmaxell
    ircmaxell almost 14 years
    Quite true, but on Linux, fork() uses copy-on-write memory sharing. So the stack would be copied, but the rest of the process would only be copied when the memory is actually changed. It's actually quite efficient (it can be more efficient than threading if you don't need IPC since it solves the processor affinity problem of threading if you have more than 1 CPU)...
  • webbiedave
    webbiedave almost 14 years
    Right. It will depend on how the OP uses the processes if such overhead will be invoked or not.
  • binaryLV
    binaryLV almost 14 years
    I also thought that PHP does not have such functionality, but I wasn't sure, so I asked here, and it turns out that PCNTL might do the trick.