Improved Thread Simulation Class for PHP
Threads. Most PHP scripts do just fine without them. However, when you venture into the domain of complex and numerous database operations, or when you need to deal with datasources of high latency (to put it plainly, HTTP downloads), the multithreading concept starts to look more attractive.
Threading support in PHP is so-so, and the pcntl extension doesn’t work on Windows. Since I’m too lazy to boot up Linux just for the sake of PHP development, I once again went looking for ways to simulate threads (I’ve written about this before).
I created two classes that use asynchronous HTTP POST requests to simulate multithreading (inspired by this class). The Thread simulates a single thread of execution, whereas ThreadManager is an utility class that makes handling multiple threads easier. The script is a bit too long to post here, so …
Download It
thread.zip (3 KB)
Check the examples below for how to use the classes.
Usage Examples
Here you’ll find a few examples of how to use the two classes. You can also take a look inside thread.php for additional info – most class methods contain explanatory comments.
The next code block is common for all examples. In it I include the thread.php file to get access to the classes, and define the test() function which I will use as the example thread function. test($s) simply sleeps for $s seconds and returns a message telling how long it slept.
include_once("includes/thread.php"); function test($s){ sleep($s); return $s." seconds have passed."; }
Using the Thread class
This example will create two simulated threads and execute them simultaneously. Note that this isn’t the way I’d do it, as handling multiple threads this way is a hassle. However, it shows the basic functions of the class.
$program_start_time = microtime(true); //Create to thread $thread1 = new Thread; /*Set the thread function to execute, and it's arguments. Every argument should be passed as an element of the array. The thread function receives the arguments normally.*/ $thread1->setFunc('test', array(3)); //Start the thread $thread1->start(); $thread2 = new Thread; $thread2->setFunc('test', array(5)); $thread2->start(); //Wait while the threads are running while (!$thread1->finished || !$thread2->finished){ $thread1->query(); $thread2->query(); /* query($seconds, $useconds) waits for a specified time for the thread and processes it's output (if available), filling the Thread::response and Thread::result fields. Returns TRUE if the thread is still running, FALSE otherwise.*/ } //Output the results echo "Thread1 : ", $thread1->result,"<br>\n"; echo "Thread2 : ", $thread2->result,"<br>\n"; echo "Total execution time : ".(microtime(true)-$program_start_time)." seconds<br />";
You should get output similar to this :
Thread1 : 3 seconds have passed. Thread2 : 5 seconds have passed. Total execution time : 5.01491904259 seconds
Note that you can’t pass resource handles to the thread function. Only variables that can be handled by var_export will work.
Using the ThreadManager class
This is functionally equivalent to the previous example, but more elegant.
$program_start_time = microtime(true); //Create a ThreadManager instance with default settings $manager = new ThreadManager; //Create and start two threads. $manager->create_thread('test', array(3)); $manager->create_thread('test', array(5)); /* Wait until all threads are finished. ThreadManager::query() processes all threads and returns the number of threads that are still executing. Check class definition for details.*/ while ($manager->query()); //Output the results foreach ($manager->finished_threads as $id => $thread){ echo "Thread '$id' : ", $thread->result,"<br>\n"; } echo "Total execution time : ".(microtime(true)-$program_start_time)." seconds<br />";
The expected output is something like this :
Thread '_thread_1' : 3 seconds have passed. Thread '_thread_2' : 5 seconds have passed. Total execution time : 5.01980900764 seconds
ThreadManager also has a handy pop_finished_thread() function which returns a finished thread and removes it from managers internal lists.
Final Notes
I’m using the class in my DA recommender project and it seems to be working nicely so far. If you have any questions, feel free to comment
I have tried the class on two different server environments both give me an error 404!
Is there anything I need to check?
@Chris – I take that back- it now gives me a decoding error. Will keep playing.
@Chris – Got the example code to work. However when running it through my code I get a decoding error
@Chris – It has been quite a while since I wrote/used this class, so I don’t have any ideas off-hand. Anyway, I’d start looking at the “The response was :” part to see why the response can’t be decoded, and work from there.
Доброго времени суток! Мне вот тут стало интересно, а есть какие-нибудь он-лайн школы, курсы или что-то подобное, где учат на веб-мастеров? Пытаюсь найти, но ничего не нахожу. Очень хочу стать веб-мастером, слышал, что они хорошо получают. И вообще очень интересно, как это так они работают? И есть ли какие-нибудь спецпредметы, или ещё какие-нибудь специальные дисциплины, которые веб-мастерам знать обязательно? Может кто поможет, если не сложно?
Слышал, что новичков в этой среде не очень любят – и как тогда быть?
Извините, а вы случайно не спамер? Коммент вроде бы оффтопик, да и на русском… подозрителъно, тощарищ
You have to replace “localhost” in the create_thread function to get rid of the decoding error (Line 287)
Also the “emtpy” should be “empty” on line 40
Hope this help anyone in the future.
Other than that it is great code.
Thanks!
Okay, I fixed some of those bugs.
[...] [...]
Yo!
How are you doing?
I am new at w-shadow.com and thought I would say HI
I hope I can become a contributing member!
Oh yeah… because the economy is so corrupt right now.. I cant afford music.. lol
Anyone know where I can get free itunes gift cards online?
Sorry if this is in wrong section admin.. wasnt sure of the right place.
Thank You!!
[...] http://www.phpclasses.org/browse/package/3953.html [14] Improved Thread Simulation Class for PHP http://w-shadow.com/blog/2008/05/24/improved-thread-simulation-class-for-php/ Author: Anton Vedeshin Categories: Articles Tags: Distributed Computing, PHP Comments (0) [...]
I have this working fine on my workstation using XAMPP but when I publish to my production Apache server I get the following
Decoding error! The response was : HTTP/1.1 404 Not Found Date: Tue, 01 Sep 2009 18:47:57 GMT Server: Apache/2.0.63 (Unix) mod_ssl/2.0.63 OpenSSL/0.9.7a mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 PHP/5.2.5 Accept-Ranges: bytes Connection: close Transfer-Encoding: chunked Content-Type: text/html 1 1 95
16 404 Not Found
43 The server can not find the requested page:
9 localhost 17 /multithread.php (port 41 80)
Please forward this error screen to 21 localhost’s WebMaster.
Looks like the script incorrectly determines the current URL. Take a look at the constructor of the Thread class + the Thread->start() method and see if anything looks wrong to you. Also, you might need to explicitly specify the domain name when creating a thread.