SRL Archive - Web Development

PHP Threads


superuser

2012-01-29 13:00:45

Hello,

I case anybody ever wondered, it's possible to launch threads in PHP. However, currently it's possible only on *nix environments, due to the fact that libpcntl is not supported in Windows.

Here's the class:

[php]<?php

/** A class to spawn a thread. Only works in *nix environments, as Windows platform is missing libpcntl.
* Forks the process.
*
* @author Superuser
* @version $Id: Thread.class.php 23 2012-01-23 09:40:32Z superuser $
*/

class Thread
{
public function __construct($callback = null)
{
if (!function_exists('pcntl_fork'))
throw new Exception('PHP is compiled without –enable-pcntl');

if ($callback != null)
$this->SetCallback($callback);
}

public function IsAlive()
{
return (pcntl_waitpid($this->_pid, $status, WNOHANG) === 0);
}

public function SetCallback($callback)
{
if (function_exists($callback) && is_callable($callback))
$this->_callback = $callback;
else
throw new Exception("$callback is not valid function");
}

public function Start()
{
if (($this->_pid = pcntl_fork()) == -1)
throw new Exception('Couldn\'t fork the process');

if (!$this->_pid) {
// Child.

pcntl_signal(SIGTERM, array($this, 'SignalHandler'));

$args = func_get_args();

!empty($args) ? call_user_func_array($this->_callback, $args) : call_user_func($this->_callback);

exit(0);
}

// Parent.
}

public function Stop($signal = SIGKILL, $wait = false)
{
if ($this->IsAlive()) {
posix_kill($this->_pid, $signal);

if ($wait)
pcntl_waitpid($this->_pid, $status);
}
}

private function SignalHandler($signal)
{
switch ($signal) {
case SIGTERM:
exit(0);
}
}

private $_callback, $_pid;
}[/php]

The class works like this:

[php]<?php

require_once('Thread.class.php');

function Foo($t)
{
for ($i = 0; $i < 10; $i++) {
echo "Hello from thread #{$t + 1}. i=$i" . PHP_EOL;

sleep(1);
}
}

try {
$t = array();

for ($i = 0; $i < 10; $i++) {
$thr = new Thread('Foo');

$thr->Start($i);

$t[] = $thr;
}

$done = false;

while (!$done) {
sleep(1);

$done = true;

foreach ($t as $thread)
if ($thread->IsAlive()) {
$done = false;

break;
}
}
} catch (Exception $e) {
echo 'Exception: ' . $e . PHP_EOL;
}
[/php]

Enjoy!

Brandon

2012-01-29 13:06:42

Tried LibCurl?

superuser

2012-01-29 13:11:11

From: ggzz
Tried LibCurl?


Of course, why?

Brandon

2012-01-29 13:14:32

From: superuser
Of course, why?


Doesn't lib curl have multi-threading for php? I believe it does..

superuser

2012-01-29 19:22:03

From: ggzz
Doesn't lib curl have multi-threading for php? I believe it does..


What? I'm most sure it doesn't :)

Edit:

Apparently there's some way of using cURL for threading..

Brandon

2012-01-29 19:24:57

It most certainly does :S
http://codestips.com/php-multithreading-using-curl/

StackOverflow also has examples on this..

Yes I know what curl is for, I have that and the boost library for C++, PHP, and Java.

Edit:
Unless your not trying to do parallel url grabbing.. then I don't think PHP can do that..

superuser

2012-01-29 19:33:54

From: ggzz
It most certainly does :S
http://codestips.com/php-multithreading-using-curl/

StackOverflow also has examples on this..

Yes I know what curl is for, I have that and the boost library for C++, PHP, and Java.

Edit:
Unless your not trying to do parallel url grabbing.. then I don't think PHP can do that..


PHP can do it, in *nix environments. The magic behind it is forking processes. With the very same technique, you can create even PHP daemons.