Executing functions parallelly in PHP

拟墨画扇 提交于 2020-01-21 01:41:49

问题


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!


回答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).




回答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.




回答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.




回答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.




回答5:


PHP doesn't have this functionality as far as I know

You can emulate the function using a different technique, like this one: Parallel functions in PHP




回答6:


PHP does not support multi-threading, so there's no other option than taking advantage of the OS or the web server multi processing capabilities. Note that actually you can fetch both the result and output of exec:

string exec ( string $command [, array &$output [, int &$return_var ]] )




回答7:


You can, at least, prevent the parent process from hanging until the child process is done by ignoring the child signals using pcntl_signal(SIGCHLD, SIG_IGN).

So, let's say you want to fork a process and execute another PHP function that takes a while without making the parent wait for it to finish (since you want the main process to finish in a timely manner):

pcntl_signal(SIGCHLD, SIG_IGN);
$pid = pcntl_fork();
if ($pid < 0) {
  exit(0);
} elseif (!$pid) {
  my_slow_function();
  exit(0);
}
// Parent keeps executing and finishes before the child does

If you want to execute a slow external script as the child process, pcntl_exec is handy:

$script = array('/path/to/my/script'); // E.g. /home/my_user/my_script.php
pcntl_exec('/path/to/program/executable',$script); // E.g. /usr/bin/php


来源:https://stackoverflow.com/questions/2998314/executing-functions-parallelly-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!