Ibuildings Blogs
Monday, March 31. 2008Comments
Display comments as
(Linear | Threaded)
Interesting thought.
You can also make PHP 'multitask' using the Unix Fork functionality with the pcntl PHP extension. pcntl allows your script to create child processes that run independently from the point they were created. However, these child processes are not threads and variables are not shared. Sharing data between threads may be acheived using shared memory or something similar.
The task at hand can be completed without using curl.
http://php.net/stream http://netevil.org/blog/2005/may/guru-multiplexing
I'm not quite sure you can use streams for this kind of multitasking as streams are blocking the script execution while fetching / sending data, while (as I see it) running external cURL process dosn't, else it would still be less usefull than a real multitasking / threading mode.
> .. streams are blocking ..
http://php.net/stream_set_blocking > .. less usefull .. For "retrieving content from several url's at the same time" you don't need multitasking/forking. also, cURL is not available on every system, but that can be 'fixed' (assuming one has root priviledges).
popen dose a similar thing
and u can also launch paralel local php scripts (command line mode)
Rob Young's phpmio can help with this too, but in a more generic way. http://sourceforge.net/projects/phpmio
Thanks yagitoshiro, you're absolutely right. I will change this.
I still think the best way to simulate multithreading in PHP is running more than one PHP processes using popen or proc_open. That's as close as you can get to multithreading (I think)...
same as [utl="http://bg.php.net/manual/en/function.proc-open.php"]proc_open()[/url]
I've tried a similar approach (listed also at various php forums) months ago.
I had to use 4 threads for requesting large XML data with response times up to 20sec, for a project of my company. While the request was at the "running" loop, the CPU utilization was up to 100% in a dual Xeon 5110 system with 8Gb or RAM!!! Unfortunately for me, I had to build a java application under Tomcat in order to manipulate the threading request. So, according my experience this script isn't acceptable, unless you have small response times from your CURLed requests.
1 - I consider this for loop use as false multithreading because each call is made once the previous is done.
2 - The use of your for loop may severly slow down your script if you have too many URL to call and may die 3 - I needed this kind of thing for an online game witch had to return results as fast as possible. I first started like you to make my script as dynamic as possible but went through speed issues So, I used the following scheme: call 1 call 2 call 3 while(expecting_results){do nothing} ....(rest of the script) (of course, it's less dynamic but way faster)
djStelios, thanks for sharing your experiences. In my use of this approach, i didn't run into problems but the resonse time of my urls is much faster than yours. But i'll keep it mind.
Michael: can you explain what you did with a code example? I don't quite understand the call 1, call 2, call 3. And why is the for loop false? The calls are already executed but we need to get the results from curl with a for loop. Maybe there are better ways?
Michael is right, for 1 and 2.
You can try it by yourself if you have bigger timeouts at your script. For example you can start from $i=6 to $i smaller than 25 with increment of 6. (Sorry for description of the loop. The "smaller than" in the code does not work at this textarea nor the [code] tag of the BBCode)
Ok, let's take an example to illustrate what I said:
function multiThread(){ $result1 = call($url1); //call() uses cURL thing... $result2 = call($url2); return array($result1, $result2); } PHP is not asynchronous: call($url2) will not wait for $result1 to get its result to start its call. So you're function will return an array of empty values; So you need to make the script wait before you return something. And you do this that way: function multiThread(){ $result1 = call($url1); //call() uses cURL stuff of course... $result2 = call($url2); while(!$result1 && !$result2){} return array($result1, $result2); }
Efficiency might be improved by incorporating the curl_multi_select function; it essentially runs a system select() call on all the sockets, which lets the kernel notify you when data has arrived.
This is a joke, right? Who could possibly think this is a good idea?
This is really a very very bad idea. It resembles misuse of the anchor tag in html to achieve the same goal. Also, this has nothing to do with proper software design/ architecture. To name some implementation problems: What about exception handling in "worker" threads, do name "something", or socket exhaustion?
PHP isn't a multithreaded language (besides from the pnctl module) so do not try to "make" (force) it multithreaded in very unstable ways as the result may be not what you expect!! You are bringing bad ideas to inexperienced coders, please consider removing the blog entry.
As described in the article this is not real multithreading. And i also mentioned the problem about exception handling.
However this is usefull if you need content from multiple websites and you don't want to get the content sequential because you have to wait longer. Ofcourse whether you want to use it or not is your own choice. |
Ibuildings - Ibuildings Blogs
Tracked: Apr 01, 16:15