Adding Multi-Threading to PHP (Purely New Idea Try it)

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

jbr
Forum Newbie
Posts: 2
Joined: Mon Oct 11, 2004 9:26 pm

Post by jbr »

I don't know why one would say PHP doesn't support multi threading, because it does for certain streams, especial when working with sockets. You can have as many threads running within a single script that the OS supports. So downloading or fetching content from as many connections/threads as you want at the same time, in parallel is a simple task.

I'll give a simple example....

This is array of URLS to fetch.

// the array of url(s) to fetch

Code: Select all

$file = array ( 
		array ( 'url' => 'http://www.msn.com' ), 
		array ( 'url' => 'http://forums.devnetwork.net/' ), 
		array ( 'url' => 'http://www.adobe.com' ), 
		array ( 'url' => 'http://www.yahoo.com' ), 
		array ( 'url' => 'http://www.google.com' ), 
		array ( 'url' => 'http://www.php.net' ), 
		array ( 'url' => 'http://www.perl.com' ), 
		array ( 'url' => 'http://www.phpfreaks.com' ), 
		array ( 'url' => 'http://www.microsoft.com' ), 
		array ( 'url' => 'http://froogle.google.com/' ), 
		array ( 'url' => 'http://www.microsoft.com/windows/default.mspx' )
	);
The http_parallel class I am using is setup to only use a maximum of 5 threads at one time, when a thread is killed the class will create a new thread always only keeping 5 active threads running. Because the class works in parallel, what ever thread is done first will display the result first. So even though each url in the above $file array will be executed in that exact order, they will not return in that order because reading and writing is done using unique threads, so what ever thread finishes with it's reading and writing first will display it's results. This is pure PHP multi-threading on a multi-thread server.


http://www.phpbyexample.com/example.php
ASDen
Forum Commoner
Posts: 55
Joined: Fri Aug 24, 2007 10:27 am

Post by ASDen »

To n00b Saibot :-
do some defensive coding to get around it.
Well it's only a dynamic thread display issue but threading is working
IE7 supports XHR object natively
it does but the implementation is bad it does not raise the event of readystate=3
lastly, word is `violate` instead of `volatile`
Well..... I meant that it's support is 'volatile' and Makes some Ajax Features 'volatile' :D :D :oops: :oops:
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

~jbr, it's true that fsockopen() will allow multiple requests to execute in parallel and that the quickest one will end first. My colleague has written classes which wrap this functionality to delegate jobs across multiple requests. However, that's not PHP (the language) multithreading, it's the interpreter. PHP as a language does not support multithreading and that's just fact ;)
User avatar
The Phoenix
Forum Contributor
Posts: 294
Joined: Fri Oct 06, 2006 8:12 pm

Post by The Phoenix »

d11wtq wrote:~jbr, it's true that fsockopen() will allow multiple requests to execute in parallel and that the quickest one will end first. My colleague has written classes which wrap this functionality to delegate jobs across multiple requests. However, that's not PHP (the language) multithreading, it's the interpreter. PHP as a language does not support multithreading and that's just fact ;)
Notably, that is multiple requests, not multiple threads.
ASDen
Forum Commoner
Posts: 55
Joined: Fri Aug 24, 2007 10:27 am

Post by ASDen »

where is your ideas about the MySql idea ? have you forgot it :D ?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

ASDen wrote:where is your ideas about the MySql idea ?
In the entirety of this thread you have mentioned MySQL three times including this. Twice in another post. That post had no bearing on this thread that I can tell.
ASDen
Forum Commoner
Posts: 55
Joined: Fri Aug 24, 2007 10:27 am

Post by ASDen »

That post had no bearing on this thread that I can tell.
I didn't understand this ? do you mean you didn't understand that post ?
I meant : i've coded another way of communication between threads that is much faster & trusted more in Syncronization
this way is based on MySql Heap Engine/Table for using Memory not files which isn't available in all free host . So i thinked of it as an optimized alternative
i haven't put it in SF yet . and i need to hear from you what do you think about this idea ?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

ASDen wrote:I didn't understand this ? do you mean you didn't understand that post ?
I meant : i've coded another way of communication between threads that is much faster & trusted more in Syncronization
this way is based on MySql Heap Engine/Table for using Memory not files which isn't available in all free host . So i thinked of it as an optimized alternative
i haven't put it in SF yet . and i need to hear from you what do you think about this idea ?
If your code still relies on Ajax and/or Javascript I will say only one thing: it's massively flawed.
ASDen
Forum Commoner
Posts: 55
Joined: Fri Aug 24, 2007 10:27 am

Post by ASDen »

Back from feyd interrupt in which i didn't understand what he added to his early posts ......... Anyway:-
first i reconstructed communication between threads , first there is an abstract class every communication class inherits which made development more flexible & easier .
one last thing to add is the class has been nominated for innovation contest at PHPClasses.org

Here is MySql communication code

MyCom.php

Code: Select all

<?php
require("Com.php");
class MyCom extends ComBasic
{
	private  $Mylnk;
	public   $Table;
	function MyCom($hostname,$username,$pass,$DB,$Tablename="")
	{
		$this->Mylnk=mysql_connect($hostname,$username,$pass);
		mysql_select_db($DB,$this->Mylnk);
		$this->Table=$Tablename;
	}
	function Init()
	{
		$i=-1;
		do {
			$i++;
			$n="Process".$i;
			$res=mysql_query("CREATE TABLE $n(Prob char(255) PRIMARY KEY,Val char(255))ENGINE=HEAP",$this->Mylnk);
		}while ($res==false);
		$this->Table="Process".$i;
	}
	function Set($name,$value)
	{

		$res=mysql_query("INSERT INTO $this->Table VALUES ('$name','$value')",$this->Mylnk);
		if ($res==false)
		{
			$res=mysql_query("UPDATE $this->Table SET Val='$value' WHERE Prob='$name'",$this->Mylnk);
		}
		return $res;
	}
	function Get($name)
	{
		$res=mysql_query("SELECT Val FROM $this->Table WHERE Prob='$name'",$this->Mylnk);
		if ($res!=false)
		{
			$row = mysql_fetch_array($res);
			return  $row['Val'];
		}
		return $res;
	}
	function Clear()
	{
		mysql_query("DROP TABLE $this->Table");
	}
}
?>
the previous sample now Jsim.php looks after adding :-
1. the Process idea which holds the communication lines
2. New Communication Methods (Files & MySql)
Jsim.php using MyCom

Code: Select all

<div id="M"></div>
<?php
require_once("Threader.php");
require_once("Com/MyCom.php");
$fcom=new MyCom("","root","","test");
$P=new Process($fcom);
$e=new Thread("Counter.php","UN=$fcom->Table",$p);
$s=new Thread("Echoer.php","UN=$fcom->Table",$p);
$e->Go();
$s->Go();
?>
Jsim.php using Files

Code: Select all

<div id="M"></div>
<?php
require_once("Threader.php");
require_once("Com/FileCom.php");
$fcom=new MyCom("Jsim");
$P=new Process($fcom);
$e=new Thread("Counter.php","UN=$fcom->UniqueName",$p);
$s=new Thread("Echoer.php","UN=$fcom->UniqueName",$p);
$e->Go();
$s->Go();
?>
The new version is now available at http://www.phpclasses.org/browse/package/4082.html
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

I'm not sure I understand why it would be important for code to work on a free host. I've never even heard of a free php host, let alone used one.
ASDen
Forum Commoner
Posts: 55
Joined: Fri Aug 24, 2007 10:27 am

Post by ASDen »

To The Ninja Space Goat :-
does this mean you liked MySql implementation Or just liked to mention the point of free hosts that i don't agree to with you , I think free hosts is a big marking point between PHP & ASP . i can't think of a one starting big project without a free host for Beginning / Testing , Or paying in a small project were it can avoid
as a last thing
I've never even heard of a free php host
It's your ears check them :D :D :D
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Post by John Cartwright »

ASDen wrote:i can't think of a one starting big project without a free host for Beginning / Testing , Or paying in a small project were it can avoidas a last thing
http://localhost ?
ASDen
Forum Commoner
Posts: 55
Joined: Fri Aug 24, 2007 10:27 am

Post by ASDen »

I want to say two things :-
1. Please , this is NOT the main topic this is a very sub and i received no answer to the main topic ,so don't follow the wind .
2. localhost is more than unacceptable answer , think over , checking traffic-bear , making some reputation before moving to a paid thing , even real relative speed , security holes as it's accessible even for checkers only & so many to go

BUT again this is not the main topic we were talking about MySql implementations gives & takes
ASDen
Forum Commoner
Posts: 55
Joined: Fri Aug 24, 2007 10:27 am

Post by ASDen »

I've gone more in the abstract class idea and provided one also for calling the threads this made it very easy to implement the Sockets idea with no miss up and maintain good binding of the code (i haven't uploaded yet to SF for any suggestions of you first ) .

Code: Select all

<?php
/*Author :ASDen(Mohammed Yousef)
Country:Egypt
Email  :harrrrpo@gmail.com
Email me for any help or just encourage me and tell me it does work !
The PHP Class implementing the Js Class */
require "Caller.php";
class SocThread extends CallerBasic
{
	private $Host;
	private $params;
	function __construct($url,$params,$MothProcess)
	{
		CallerBasic::__construct($url,$params,$MothProcess);
		$this->Host=$url;
		$this->params=$params;
	}
	function Go()
	{
		$ar=Parse_url($this->Host);
		$HostQ=$ar['host'];
		$URI=$ar["path"];
		$ReqBody=$this->params;
		$ContentLength=strlen($ReqBody);
		$ReqHeader =
		"POST $URI HTTP/1.1\n".
		"Host: $HostQ\n".
		"Content-Type: application/x-www-form-urlencoded\n".
		"Content-Length: $ContentLength\n\n".
		"$ReqBody\n".
		//"Connection: close\n";
		$socket = fsockopen($HostQ, 80, &$errno, &$errstr);
		fputs($socket, $ReqHeader);
		fclose($socket);
	}
}
?>
I tested the Ajax Implementation vs. the Sockets Implementations in Win xp ( FF & Opera & IE & Safari ) the Results :-
the thread used for testing is a simple one

Code: Select all

<?php
sleep(2);
$f=fopen($_POST["P"],"w");
?>
And it was called 1000 times :-
Memory :
Sockets : Apache process used Memory raised 150M
Ajax : Apache process used Memory raised ~4M
Speed:

Sockets were of course Much faster but there server load was severe

one thing also to note is the high CPU Usage of client (browser) in Ajax Method :-
FF : 50%
Opera :started at 50% but went down steadily to 20%~25%
Safari :Amazingly started at 5%~6% ending in about 12% (But slower than others)
IE :Behaved strangely first it's memory usage rose 150M with a cpu usage of 1~2% then dropped down 130M and cpu usage rised to
50% after that the execution stopped without finishing/calling all threads (~300 only)

of course in Sockets case non of this happened as full load is on server

I'd like to hear from u About Results & should i add sockets approach or not
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

It looks interesting. One small twiggle - you should probably find a new replacement for "thread". What's going on here is not created new threads of execution, but spawning new processes (whether all-new or children). Both may look the same, but there are differences outside of concurrency. Just a small confusing terminology thought ;). Be careful with the Ajax option - browsers are limited in the number of requests per unique domain which will slow it down.
Post Reply