Is PHP supporting multithreading? The answer is NO, if you are excluding the interop mechanism.
First of all, let me tell you a story about Threading. A CPU (computer’s processor) can have one or multiple cores. Each core can have one or multiple processes spawned by applications which in turn can be forked with child processes. Each process / child process can have one or multiple threads which are “the smallest unit of processing that can be scheduled by an operating system” (Wikipedia). Further down, Microsoft comes with a concept of task, which is included in the latest version of the .NET Framework – Parallel Framework (PFX).
For Unix we have http://www.php.net/manual/en/intro.posix.php andhttp://www.php.net/manual/en/intro.pcntl.php which are a set of complementary libraries that allows process manipulation operations. Let me repeat that: “process manipulation operations”… since there is nothing mentioned about threading, you can simply put it this way: PHP doesn’t natively support threading in Unix through the libraries mentioned above, instead it supports process forking. As you may already noticed, I used the term of “natively” because you can achive multithreading by interoping with languages like Java, C / C++ or even .NET through Mono. If you may wonder what are the advantages of using threads over processes in general, read thishttp://www.programmerinterview.com/index.php/operating-systems/thread-vs-process/; in particular, each language can have it’s own mechanisms of dealing with threads. A nice article on “multithreading” in PHP can be found on my comrade’s blog Tudor a.k.a. motaneluhttp://blog.motane.lu/2009/01/02/multithreading-in-php/.
Since posix and pcntl libraries are not supported on Windows, I’m going to assume that some of you who are running PHP under Apache / IIS on Windows will still want at some point to multithread the application. Have no fear, .NET is here! If you are familiar with C#, VB.NET or maybe F#, you can easily take advantage of the interoperability between PHP and .NET through the DOTNET classhttp://www.php.net/manual/en/class.dotnet.php and with it of all the goodies that the .NET Framework 4.0 is made of: PLINQ, Parallel class, task parallelism, concurrent collections and other. Make no mistake, as I already mentioned, the interop mechanism can be also used from Unix in pair with some languages, but since I primarily am a .NET programmer, I’m going to explain this through C# code.
I will assume that you have installed at least Visual C# 2010 Express Edition. First create a new Class Library project: File -> New Project -> Class Library. We’re going to call it MultithreadedDotNetClass. The purpose of this library is to add random numbers from multiple threads, avoiding duplicates. I will attach the source code here http://goo.gl/1so4v
In order to install the new assembly in the GAC, so that we could use it with the DOTNET PHP class, we need to sign it with a strong name. You can either do this from the IDE or with the SN tool from the .NET SDK. I will do this from the IDE, by going to Project -> MultithreadedDotNetClass Properties… -> Signing -> Sign the assembly.
Before building the library, I will make this assembly visible to COM components by setting the [assembly: ComVisible()] attribute to true (by default is false). Now you can finally build it.
Now let’s install our assembly in the GAC. Open a new command prompt, go to the location where gacutil is installed and type the following:
gacutil -I "C:\Path\To\The\Library\MultithreadedDotNetClass.dll"
For the test create a new PHP file, test.php, with the following content, replacing the Version / PublicKeyToken with your own:
$multithreadedDotNetObject = new DOTNET('MultithreadedDotNetClass, Version=220.127.116.11, Culture=neutral, PublicKeyToken=b9137eaca16ad247', 'MultithreadedDotNetClass.Program'); $multithreadedDotNetObject->DoWork();
If you have trouble in finding the Version / PublicKeyToken for the MultithreadedDotNetClass assembly, type this in the command prompt:
gacutil /lr MultithreadedDotNetClass
The result will be the Strong Name of the assembly:
After running our test, the output is as expected: