views:

7672

answers:

6

I found this PECL package called threads, but there is not a release yet. And nothing is coming up on the PHP website.

+7  A: 

There is nothing available that I'm aware of. The next best thing would be to simply have one script execute another via CLI, but that's a bit rudimentary. Depending on what you are trying to do and how complex it is, this may or may not be an option.

Wilco
That's what I thought. I saw a bunch of older postings saying no, and nothing on php.net, so this was my thought. Thanks for confirming it.
Thomas Owens
Yeah, that PECL package is kind of a tease - I ran across it as well but nothing has ever come of it.
Wilco
+7  A: 

You can use pcntl_fork() to achieve something similar to threads. Technically it's separate processes, so the communication between the two is not as simple with threads, and I believe it will not work if PHP is called by apache.

davr
I'm successfully using pcntl_fork to parallelize a pretty massive data import task. Works great, and I had it working in about an hour. There's a bit of a learning curve, but once you understand what's going on, it's pretty straight forward.
Frank Farmer
Frank, is that with CLI php or apache PHP?
Artem Russakovskii
@Artem: I'd like to know too.
Josh K
+6  A: 

Here is an example of what Wilco suggested:

$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & echo $!';
$pid = shell_exec($cmd);

Basically this executes the PHP script at the command line, but immediately returns the PID and then runs in the background. (The echo $! ensures nothing else is returned other than the PID.) This allows your PHP script to continue or quit if you want. When I have used this, I have redirected the user to another page, where every 5 to 60 seconds an AJAX call is made to check if the report is still running. (I have a table to store the gen_id and the user it's related to.) The check script runs the following:

exec('ps ' . $pid), $processState);
if (count($processState) < 2) {
     // more than 1 row in the ps, therefore report is complete
}

There is a short post on this technique here: http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/

Darryl Hein
+1  A: 

There is the rather obscure, and soon to be deprecated, feature called ticks. The only thing I have ever used it for, is to allow a script to capture SIGKILL (Ctrl+C) and close down gracefully.

troelskn
+1  A: 

pcntl_fork() is what you are searching for, but its process forking not threading. so you will have the problem of data exchange. to solve them you can use phps semaphore functions (http://www.php.net/manual/de/ref.sem.php) message queues may be a bit easier for the beginning than shared memory segments. anyways, a strategy i am using in a web framework that i am developing which loads resource intensive blocks of a webpage (probably with external requests) parallel: i am doing a job queue to know what data i am waiting for and then i fork off the jobs for every process. once done they store their data in the apc cache under a unique key the parent process can access. once every data is there it continues. i am using simple usleep() to wait because inter process communication is not possible in apache (children will loose the connectino to their parents and become zombies...). so this brings me to the last thing: its important to self kill every child! there are as well classes that fork processes but keep data, i didn't examine them but zend framework has one, and they usually do slow but reliably code. you can find it here: http://zendframework.com/manual/1.9/en/zendx.console.process.unix.overview.html i think they use shm segments! well last but not least there is an error on this zend website, minor mistake in the example.

while ($process1->isRunning() && $process2->isRunning()) { sleep(1); } should of course be: while ($process1->isRunning() || $process2->isRunning()) { sleep(1); }

Joe Hopfgartner
A: 

If anyone cares, I have revived php_threading (not the same as threads but similar) and I actually have it to the point where it works (somewhat) well!

project page: http://github.com/alecgorge/php_threading

download (for Windows PHP 5.3 VC9 TS): http://github.com/alecgorge/php_threading/raw/master/binaries/Release/php_threading.dll

examples: http://github.com/alecgorge/php_threading/tree/master/source/samples/

don't forget to read the readme: http://github.com/alecgorge/php_threading/blob/master/README.markdown

Ramblingwood