17

In PHP we normally do coding without considering what the server is capable of. Now a days even PCs have multiple cores and process 64 bit data also. As far as I know the PHP engine itself is optimised to take advantage of multiple cores. How can we programmers can optimize further the code to take advantage of multiple cores.

In other words I want to know the techniques that will teach me to write code which will be more likely to be considered by php engine to process parallely.

I'm not asking for any user defined / open source queuing method but to write the same code in such a way that it takes advantage of multi core and works faster.

Please suggest your thoughts and share your experience if you already are doing something like this.

I am hoping there should be way we can optimize code further.

Airy
  • 5,484
  • 7
  • 53
  • 78
Imdad
  • 5,942
  • 4
  • 33
  • 53
  • It can be possible duplicate of "http://stackoverflow.com/questions/6107339/parallel-processing-in-php-how-do-you-do-it" . – Debugger May 23 '12 at 06:35
  • @Debugger, That link is quite different. and asks quite different thing. tough it look similar at a glance. – Imdad May 23 '12 at 06:40
  • 2
    This is a non-issue IMO. PHP is a horribly slow, interpreted language, and if CPU is your main bottleneck, you will need to change platforms. Do you have an *actual, real-world use case* for which you need parallel processing, or where CPU is your bottleneck? If you do, you will want to move that part of the code into something that can be compiled to a binary (as an extension or a separate service) – Pekka May 23 '12 at 06:47
  • 1
    @Pekka, I'm looking for a way to write code which will be widely used in future. A better way, a faster exicution which is always good fr real word which is developing everyday. – Imdad May 23 '12 at 06:56
  • 1
    @Imdad you're worrying about something that is unlikely to ever have a real-world impact on your performance. – Pekka May 23 '12 at 06:58
  • See related question http://stackoverflow.com/questions/1532065/php-multithread. – Mihai8 Jun 06 '14 at 07:47

4 Answers4

22

PHP has had a threading model for a very long time, since the first release of PHP4, May 22nd 2000.

Threading at the frontend

Creating user threads at the frontend of a web application doesn't make any sense; it is extremely difficult to scale. The thread per client model that the Apache Worker MPM binary and mod_php employ is not really something you want to use to serve your websites, certainly if you are using it, you do not want to create additional threads in direct response to any web requests.

Why are threads at the frontend a bad idea ?

You may often hear developers say threads at the frontend do not make sense, without providing the rationale for such an assertion. When you learn to think about systems in the required way the problem becomes obvious:

If a client script creates 8 threads in direct response to a web request, and 100 clients request the script simultaneously, you are requesting that your hardware execute 800 threads concurrently.

CPU's would have to look and work very very differently indeed to make that a good idea

What can we do about it ?

Enterprising solutions might well have a PHP website facing the public, but the actual brains of the system are written in languages that have good support for those things you require to build enterprising solutions such as Java, C#, C++ or whatever the language-of-the-day is.

You should use pthreads in the same way; by designing systems whose component parts are separated from one another, only connected by well designed, high performance (RPC) API's, such that the complexity inherent in designing a multi-threaded architecture is isolated completely from your public facing websites, and the simple, scalable setup that such a website will require.

U can now haz codes

Let's start at the beginning with Hello World:

<?php
class My extends Thread {
    public function run() {
        printf("Hello World\n");
    }
}

/* create a new Thread */
$my = new My();

/* start the Thread */
$my->start();

/* do not allow PHP to manage the shutdown of your Threads */
/* if a variable goes out of scope in PHP it is destroyed */
/* joining explicitly ensures integrity of the data contained in an objects */
/* members while other contexts may be accessing them */
$my->join();
?>

Boring, but I hope you read it ;)

So in a real system, you don't really want to be creating threads so explicitly, you surely want to just submit tasks to some executor service, all of the complex systems, in the sense of their multi-tasking requirements, I have ever seen use such things ...

<?php
class My extends Threaded {
    public function run() {
        printf("Hello World from %s#%lu\n",
            __CLASS__, Thread::getCurrentThreadId());   
    }
}

/* create a Pool of four threads */
/* threads in a pool are created when required */
$pool = new Pool(4);

/* submit a few tasks to the pool */
$tasks = 100;
while ($tasks--) {
    $pool->submit(new My());
}

/* shutting down the pool is tantamount to joining all workers */
/* remember what I said about joining ? */
$pool->shutdown();
?>

I have given you very brief explanations of complicated things, you should endeavor to read all you can:

Many examples can be found here: https://github.com/krakjoe/pthreads/tree/master/examples

Disclaimer: There's nothing really wrong with a server architecture that uses threading, but the moment you start to create additional threads, you restrict it's scalability and ability to perform as it was designed, I can imagine well designed architectures that do have the ability to thread at the frontend, but it is not an easy thing to aim for. Additionally, threading is not the only thing in the toolbox when it comes to high performance web targeted applications; research all your options.

Joe Watkins
  • 17,032
  • 5
  • 41
  • 62
  • Excellent. I don't think there can be any answer better than this. Only thing to ask is, should I let apache handle threads etc and do not change my code for any additional threads? – Airy Jun 06 '14 at 11:28
  • Use the fastest setup achievable at the frontend, today that is nginx and fpm. Use a threaded architecture at the backend, written and deployed as a system service, in communication with the frontend via some sensible (RPC) API. In such a scenario, the frontend and backend are as fast as possible, and there's no user threading near the frontend, because not required there as the backend does all the hard work and has an architecture to support it. – Joe Watkins Jun 06 '14 at 14:34
  • 1
    What an answer. You rock! @JoeWatkins – Imdad Jun 07 '14 at 09:19
11

The most common way of using PHP is running it through a multi-process web server such as Apache. This means that even if PHP itself is not multi-core aware, the operating system will do its best to balance the load created by the web server processes between the available CPUs.

If you have a stand-alone long-running PHP program that you run in a process on its own, you'll have to look into either threading or breaking the program into different processes to be able to take advantage of multiple CPUs. Which is better/easier depends on your particular situation: how easy it is to break your tasks into pieces, how much inter-process/thread communication is needed, how much synchronization you need, etc.

While the standard PHP distribution itself does not seem to have threading support, there are extensions such as php-pthreads that allow the usage of the native pthreads API.

For dividing a long-running PHP program into several processes you can use the pcntl library or the proc_* families of functions. As for IPC.. again, it depends on your needs.

Rangad
  • 2,110
  • 23
  • 29
Joni
  • 108,737
  • 14
  • 143
  • 193
  • 1
    I know OS does the multicore work. But there should be a way of coding that will be more likely to be divided by OS to process in multiple Cores – Imdad May 23 '12 at 06:45
  • 3
    All decent process schedulers try to equal the load between cores. You don't have to do anything. – Joni May 23 '12 at 06:50
  • @Pekka, theoretically you are true. But as per my experience PHP performs better than other languages when you are not expecting heavy load on server like eBay or google. – Imdad May 23 '12 at 06:51
  • 3
    @Imdad "Huh"? Yes, PHP will perform better with a light load (than it would under a heavy load)... however, this doesn't imply that it will "perform better than other languages" under an arbitrary load. Of course, "good enough" is "good enough" and some large sites run on PHP... –  May 23 '12 at 06:57
1

Well as the explanation has already been provided so putting the code directly. All you asked can be achieved with Threads.

require_once( 'Thread.php' );

// test to see if threading is available
if( ! Thread::available() ) 
{
   die( 'Threads not supported' );
}

// function to be ran on separate threads
function paralel( $_limit, $_name ) 
{
    for ( $index = 0; $index < $_limit; $index++ ) 
    {
        echo 'Now running thread ' . $_name . PHP_EOL;
        sleep( 1 );
    }
}

// create 2 thread objects
$t1 = new Thread( 'paralel' );
$t2 = new Thread( 'paralel' );

// start them
$t1->start( 10, 't1' );
$t2->start( 10, 't2' );

// keep the program running until the threads finish
while( $t1->isAlive() && $t2->isAlive() ) 
{
}

Remember PHP itself doesn't support Threads. More detailed info can be found here http://blog.motane.lu/2009/01/02/multithreading-in-php/

You can also follow this answer, which explains a bit better when it's about PHP and Threads with a code example as well.

I personally would not go with PHP Threading because threads are mostly used to speed up process by splitting it into different threads and if your site is getting high traffic then OS will itself manage Processes onto different Cores of CPU. So, I don't think you should worry about PHP threading and may be this is the reason that PHP Team is not focusing on it (that's just my thought).

  • As I understand this, threads are just emulated using process forks. Shouldn't this (in theory) be way less effective than php_pthreads, which is using real threads? – Rangad Jun 05 '14 at 15:46
  • @Rangad I have provided another link which might clear everything. –  Jun 05 '14 at 15:50
-2

PHP isn't really engineered with multi-threading in mind (it's built around a short-lifetime request/response model). There are a couple of options though.

PCNTL extenstion: Spawn and manage child processes. This isn't multithreading, as each child process is a new PHP instance. It's therefore pretty resource intensive. Not available in Windows.

PThreads extension: Allows spawning and management of threads within a PHP script. It is (as far as I can tell from the docs) available on Windows, and threads should in theory at least be a bit more lightweight than spawning processes, but there are an awful lot of caveats for using it. For example, your PHP has to be compiled for thread safety, which can have a detrimental effect on performance of unthreaded code, and can prevent the use of extensions that don't support thread safety.

ReactPHP: A library of PHP code that provides things such as an event loop and non-blocking IO. It doesn't strictly speaking support threads (though I understand there's work underway to provide them), but it does provide a lot of useful functionality that should make the need for threads less pressing. https://github.com/reactphp/react/wiki/FAQ includes a discussion of the state of thread support.

GordonM
  • 31,179
  • 15
  • 87
  • 129
  • 2
    Gordon! May be I am wrong but PThreads docs state that it is just an API written entirely in PHP for the purpose of Threads so can you tell me that even PHP docs itself say that PHP does not support Threads in real then how one can develop such an API to enable us threading by any means? Does this API use some kind of CLi or other means which in return can increase system load? – Airy Jun 05 '14 at 16:10
  • 2
    The assertion that "PHP isn't really engineered with multi-threading in mind" is simply wrong; PHP has had a threading model for a long long time. That is how pthreads can maange to implement threads, because Zend supports it, rather well. – Joe Watkins Sep 14 '14 at 05:09