• Howdy! Welcome to our community of more than 130.000 members devoted to web hosting. This is a great place to get special offers from web hosts and post your own requests or ads. To start posting sign up here. Cheers! /Peo, FreeWebSpace.net
managed wordpress hosting

Multithreading in PHP

Peo

Administrator
Staff member
Admin
krakjoe posted this but it got removed during the server move (feel free to post again under your username and I'll remove this one)




Hiya chaps ... had ten minutes spare ...

Some may have heard already, others are destined to find out in the not too distant future .... after a life time of being restricted to one thing at a time (as much as makes no difference), PHP can now multithread ... so, dotted around in various places are some scraps of thought, and here comes another ...

Take a seemingly simple task, like making multiple web requests at once ... this has other solutions in PHP, but is a task we can all understand. So the plan is to make 50 requests in less than a second, downloading all responses (for later processing perhaps) ... any which way you look at it, the code will be a mess and the server heavily stressed while doing it ... it's not even something you would normally attempt to do with PHP ...

PHP:
<?php
class WebRequest extends Thread 
{
    public $url;
    public $response;
    
    public function __construct($url) {
        $this->url = $url;
    }
    
    public function run() {
        $this->response = @file_get_contents(
            $this->url);
    }
}

/* generate 50 random urls, sorry google */
$urls = array();
while (count($urls) < 50) {
    $urls[] = sprintf(
        "http://www.google.com/search?q=%s", md5(mt_rand())
    );
}
printf("------------------------------------------------\n");
printf("Testing with threads:\n");

/* start timing operations */
$start = microtime(true);

/* create and start all threads */
$threads = array();
foreach ($urls as $id => $url) {
    $threads[$id] = new WebRequest(
        $url
    );
    $threads[$id]->start();
}

/* join with all threads */
foreach ($threads as $thread)
    $thread->join();

/* say some stuff */
foreach ($threads as $thread) {
    printf("%s sent %d bytes\n", $thread->url, strlen($thread->response));
}
printf("[threads]: made %d requests in %.3f seconds\n", count($threads), microtime(true)-$start);
printf("------------------------------------------------\n");

/* this will take much longer */
printf("Testing without threads:");
$start = microtime(true);
foreach ($urls as $url) {
    printf("%s sent %d bytes\n", $url, strlen(file_get_contents($url)));
}
printf("[no threads]: made %d requests in %.3f seconds\n", count($urls), microtime(true)-$start);
printf("------------------------------------------------\n");
?>

The output of a run is below

Code:
------------------------------------------------
Testing with threads:
http://www.google.com/search?q=28232f457a894fcfa9ef2339fc7ede52 sent 50762 bytes
http://www.google.com/search?q=712bc72747cedab7f0c41b3fe9e0732c sent 50762 bytes
http://www.google.com/search?q=d0e05e8331987ee9acb79adbdbd63076 sent 50762 bytes
http://www.google.com/search?q=b3a1c42a4c46d42580976aace11752d1 sent 52210 bytes
http://www.google.com/search?q=17eef20309d7d97429c8f7c3b0ad5206 sent 50758 bytes
http://www.google.com/search?q=9963c1272eb8643e7f1d30910fc88ff3 sent 50762 bytes
http://www.google.com/search?q=0a5d2ad6d4ea8bd3640e6d86c2b08607 sent 50762 bytes
http://www.google.com/search?q=d29b95039040837b843881127cfa8cea sent 50740 bytes
http://www.google.com/search?q=7249a0fdb5082f7cf38933a5536cb828 sent 50762 bytes
http://www.google.com/search?q=e9e4e25a3172d0c5d458070126765ce2 sent 50762 bytes
http://www.google.com/search?q=27a1ba9c872e395485dce176a6a64911 sent 50762 bytes
http://www.google.com/search?q=da215592875354dae285776f7c7cc9df sent 50762 bytes
http://www.google.com/search?q=48ed174aab0f9b57b0eb06ae13fdfbcb sent 50740 bytes
http://www.google.com/search?q=a3ee479831b466844498ba36e52559f9 sent 50762 bytes
http://www.google.com/search?q=7291c5085e458fb2a017af5a0220a3a7 sent 50762 bytes
http://www.google.com/search?q=88a0cd4fb120ae2122547d2e204e8e7c sent 50762 bytes
http://www.google.com/search?q=364156ade96d64009d0932000d06fe5a sent 50762 bytes
http://www.google.com/search?q=23859e304c0324436af950cedf025833 sent 50762 bytes
http://www.google.com/search?q=2420c726aa6ba62062726ef4458db070 sent 50762 bytes
http://www.google.com/search?q=1206205f562b387a79d740ac3c3538be sent 50762 bytes
http://www.google.com/search?q=3f8f1ce0e2aa95fd70a09462be9bc80e sent 50734 bytes
http://www.google.com/search?q=3fffc90f4884e64d3bb01fbabf4d31ae sent 50762 bytes
http://www.google.com/search?q=ff9bfe9cba31195811b68b539ff39684 sent 52231 bytes
http://www.google.com/search?q=316620800664514c547574448a9f348c sent 50762 bytes
http://www.google.com/search?q=c22a0c35f5f9d925dbd805ca35209e5f sent 50762 bytes
http://www.google.com/search?q=61195d801873a4ebb96d901c95301e81 sent 52231 bytes
http://www.google.com/search?q=a981822fe6f9d9fcd96f90277f1e919e sent 50762 bytes
http://www.google.com/search?q=38596ac9b15391d1c20581f3f7e75f07 sent 52226 bytes
http://www.google.com/search?q=31bb8af2836272277d017c7a395cda04 sent 50740 bytes
http://www.google.com/search?q=6e5dde6d12cd5f57878c07ff980dad04 sent 52231 bytes
http://www.google.com/search?q=8c314223427bb84e8537b1009fa20a12 sent 50740 bytes
http://www.google.com/search?q=df572fb5c2cd5460c4e0b20452450137 sent 50762 bytes
http://www.google.com/search?q=0bc408fe038e56222b5fbc620bedd7e5 sent 50762 bytes
http://www.google.com/search?q=70566c8c06711c42283972aec22e8898 sent 50762 bytes
http://www.google.com/search?q=4cc3f2abcc63592f0bef2978124fb71d sent 50762 bytes
http://www.google.com/search?q=c721c385d52002e739b2e0237193f773 sent 53111 bytes
http://www.google.com/search?q=ee4a6beb04121d1d8e5ef8ccf8a4d3f0 sent 50762 bytes
http://www.google.com/search?q=c29a316f9a7cf3b972c03d63c41fad97 sent 50762 bytes
http://www.google.com/search?q=8a9d11ed92f236722627d3fbfa3d5e95 sent 50762 bytes
http://www.google.com/search?q=e6fac258e3434757da52e5db99e993e8 sent 50762 bytes
http://www.google.com/search?q=18659c3fb7f6c9629eb02849e3e637f7 sent 50762 bytes
http://www.google.com/search?q=4474864911e9dda490d7fb4094588962 sent 50762 bytes
http://www.google.com/search?q=3bd8a0ad85ea2a504c8415ff466c398a sent 50762 bytes
http://www.google.com/search?q=ad3e5635b34b6225727e7f6a8dd7e7d3 sent 50758 bytes
http://www.google.com/search?q=46bd949967ad751296a631a23a49c94f sent 50762 bytes
http://www.google.com/search?q=78180a6cc40aadd2d50a7f2b1cec0890 sent 50762 bytes
http://www.google.com/search?q=134d8ba0b8cd83003b8271aa3ef6e341 sent 50762 bytes
http://www.google.com/search?q=9f5f4a1481816eefca50118dc823c38d sent 50762 bytes
http://www.google.com/search?q=6d28ceeaf0a3866a9ebdeacdbd16b97a sent 50762 bytes
http://www.google.com/search?q=5f6e1c49b8c0078c68d7d10a51d8cf23 sent 50762 bytes
[threads]: made 50 requests in 0.812 seconds
------------------------------------------------
Testing without threads:http://www.google.com/search?q=28232f457a894fcfa9ef2339fc7ede52 sent 50762 bytes
http://www.google.com/search?q=712bc72747cedab7f0c41b3fe9e0732c sent 50758 bytes
http://www.google.com/search?q=d0e05e8331987ee9acb79adbdbd63076 sent 50762 bytes
http://www.google.com/search?q=b3a1c42a4c46d42580976aace11752d1 sent 52236 bytes
http://www.google.com/search?q=17eef20309d7d97429c8f7c3b0ad5206 sent 50758 bytes
http://www.google.com/search?q=9963c1272eb8643e7f1d30910fc88ff3 sent 50762 bytes
http://www.google.com/search?q=0a5d2ad6d4ea8bd3640e6d86c2b08607 sent 50762 bytes
http://www.google.com/search?q=d29b95039040837b843881127cfa8cea sent 50762 bytes
http://www.google.com/search?q=7249a0fdb5082f7cf38933a5536cb828 sent 50762 bytes
http://www.google.com/search?q=e9e4e25a3172d0c5d458070126765ce2 sent 50758 bytes
http://www.google.com/search?q=27a1ba9c872e395485dce176a6a64911 sent 50762 bytes
http://www.google.com/search?q=da215592875354dae285776f7c7cc9df sent 50762 bytes
http://www.google.com/search?q=48ed174aab0f9b57b0eb06ae13fdfbcb sent 50762 bytes
http://www.google.com/search?q=a3ee479831b466844498ba36e52559f9 sent 50762 bytes
http://www.google.com/search?q=7291c5085e458fb2a017af5a0220a3a7 sent 50762 bytes
http://www.google.com/search?q=88a0cd4fb120ae2122547d2e204e8e7c sent 50762 bytes
http://www.google.com/search?q=364156ade96d64009d0932000d06fe5a sent 50762 bytes
http://www.google.com/search?q=23859e304c0324436af950cedf025833 sent 50762 bytes
http://www.google.com/search?q=2420c726aa6ba62062726ef4458db070 sent 50762 bytes
http://www.google.com/search?q=1206205f562b387a79d740ac3c3538be sent 50762 bytes
http://www.google.com/search?q=3f8f1ce0e2aa95fd70a09462be9bc80e sent 50762 bytes
http://www.google.com/search?q=3fffc90f4884e64d3bb01fbabf4d31ae sent 50762 bytes
http://www.google.com/search?q=ff9bfe9cba31195811b68b539ff39684 sent 52231 bytes
http://www.google.com/search?q=316620800664514c547574448a9f348c sent 50762 bytes
http://www.google.com/search?q=c22a0c35f5f9d925dbd805ca35209e5f sent 50740 bytes
http://www.google.com/search?q=61195d801873a4ebb96d901c95301e81 sent 52231 bytes
http://www.google.com/search?q=a981822fe6f9d9fcd96f90277f1e919e sent 50762 bytes
http://www.google.com/search?q=38596ac9b15391d1c20581f3f7e75f07 sent 52226 bytes
http://www.google.com/search?q=31bb8af2836272277d017c7a395cda04 sent 50762 bytes
http://www.google.com/search?q=6e5dde6d12cd5f57878c07ff980dad04 sent 52231 bytes
http://www.google.com/search?q=8c314223427bb84e8537b1009fa20a12 sent 50762 bytes
http://www.google.com/search?q=df572fb5c2cd5460c4e0b20452450137 sent 50762 bytes
http://www.google.com/search?q=0bc408fe038e56222b5fbc620bedd7e5 sent 50762 bytes
http://www.google.com/search?q=70566c8c06711c42283972aec22e8898 sent 50762 bytes
http://www.google.com/search?q=4cc3f2abcc63592f0bef2978124fb71d sent 50740 bytes
http://www.google.com/search?q=c721c385d52002e739b2e0237193f773 sent 53111 bytes
http://www.google.com/search?q=ee4a6beb04121d1d8e5ef8ccf8a4d3f0 sent 50762 bytes
http://www.google.com/search?q=c29a316f9a7cf3b972c03d63c41fad97 sent 50762 bytes
http://www.google.com/search?q=8a9d11ed92f236722627d3fbfa3d5e95 sent 50762 bytes
http://www.google.com/search?q=e6fac258e3434757da52e5db99e993e8 sent 50762 bytes
http://www.google.com/search?q=18659c3fb7f6c9629eb02849e3e637f7 sent 50762 bytes
http://www.google.com/search?q=4474864911e9dda490d7fb4094588962 sent 50762 bytes
http://www.google.com/search?q=3bd8a0ad85ea2a504c8415ff466c398a sent 50762 bytes
http://www.google.com/search?q=ad3e5635b34b6225727e7f6a8dd7e7d3 sent 50762 bytes
http://www.google.com/search?q=46bd949967ad751296a631a23a49c94f sent 50740 bytes
http://www.google.com/search?q=78180a6cc40aadd2d50a7f2b1cec0890 sent 50762 bytes
http://www.google.com/search?q=134d8ba0b8cd83003b8271aa3ef6e341 sent 50762 bytes
http://www.google.com/search?q=9f5f4a1481816eefca50118dc823c38d sent 50762 bytes
http://www.google.com/search?q=6d28ceeaf0a3866a9ebdeacdbd16b97a sent 50762 bytes
http://www.google.com/search?q=5f6e1c49b8c0078c68d7d10a51d8cf23 sent 50736 bytes
[no threads]: made 50 requests in 9.336 seconds
------------------------------------------------

Note: test executed on pedestrian hardware, core i7 with 16gb of ram. On server grade, backbone connected hardware you could and should expect even better results, still this is enough to drive the point home I think ...

For those that skipped the detailed output, using threads is ten times faster and completes 50 requests in ~0.8 seconds ... without threads more than 9 seconds are required for the same operation ...

From something you wouldn't think of doing, to absolutely possible, in one neat implementation of common task ...

Click my sig, learn more ...

Nite ...

(\__/) Joe Watkins
(='.'=) Software Architect
(")_(") http://pthreads.org
Copy and paste bunny into your sig, help him gain world domination.
 
Back
Top