This article was peer reviewed by Christopher Pitt. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be! Show Table of Contents
Table of Contents
Table of Contents
PHP developers seem to rarely utilise parallelism. The appeal of the simplicity of synchronous, single-threaded programming certainly is high, but sometimes the usage of a little concurrency can bring some worthwhile performance improvements. In this article, we will be taking a look at how threading can be achieved in PHP with the pthreads extension. This will require a ZTS (Zend Thread Safety) version of PHP 7.x installed, along with the pthreads v3 installed. (At the time of writing, PHP 7.1 users will need to install from the master branch of the pthreads repo – see this article’s section for details on building third-party extensions from source.) Just as a quick clarification: pthreads v2 targets PHP 5.x and is no longer supported; pthreads v3 targets PHP 7.x and is being actively developed. A big thank you to Joe Watkins (creator of the pthreads extension) for proofreading and helping to improve my article! When not to use pthreadsBefore we move on, I would first like to clarify when you should not (as well as cannot) use the pthreads extension. In pthreads v2, the recommendation was that pthreads should not be used in a web server environment (i.e. in an FCGI process). As of pthreads v3, this recommendation has been enforced, so now you simply cannot use it in a web server environment. The two prominent reasons for this are:
That’s why threading is not a good solution in such an environment. If you’re looking for threading as a solution to IO-blocking tasks (such as performing HTTP requests), then let me point you in the direction of asynchronous programming, which can be achieved via frameworks such as Amp. SitePoint has released some excellent articles that cover this topic (such as writing asynchronous libraries and Modding Minecraft in PHP), in case you’re interested. With that out of the way, let’s jump straight into things! Handling one-off tasksSometimes, you will want to handle one-off tasks in a multi-threaded way (such as performing some IO-bound task). In such instances, the For example:
In the above, the It may not be desirable to
pollute a class’s responsibility with thread-related logic (including having to define a
Any class that needs to be run inside of a separate thread must extend the Let’s take a quick look at the hierarchy of classes exposed by pthreads:
We’ve already seen and learnt the basics about the Recycling threadsSpinning up a new thread for every task to be parallelised is expensive. This is because a shared-nothing architecture must be
employed by pthreads in order to achieve threading inside PHP. What this means is that the entire execution context of the current instance of PHP’s interpreter (including every class, interface, trait, and function) must be copied for each thread created. Since this incurs a noticeable performance impact, a thread should always be reused when possible. Threads may be reused in two ways: with The Here’s a quick example:
Output: The above stacks 15 tasks onto the new The Another way to reuse a thread when executing many tasks is to use a thread pool (via the Let’s adapt the above example to use a pool of workers instead:
Output: There are a few notable differences between using a pool as opposed to a worker. Firstly, pools do not need to be manually started, they begin executing tasks as soon as they become available. Secondly, we submit tasks to the pool, rather than stack them. Also, the As a matter of good practice, workers and pools should always have their tasks collected once finished, and be manually shut down. Threads created via the pthreads and (im)mutabilityThe final class to cover is Let’s take a quick look at an example to demonstrate the new immutability constraints:
We can see that the There’s just one last fundamental topic to cover with respect to mutability and the Let’s again take a quick look at an example to better understand things:
We can see that As a demonstration:
Other supported operations include SynchronizationThe final topic we will be covering in this article is synchronization in pthreads. Synchronization is a technique for enabling controlled access to shared resources. For example, let’s implement a naive counter:
Without using synchronization, the output isn’t deterministic. Multiple threads writing to a single variable without controlled access has caused updates to be lost. Let’s rectify this by adding synchronization so that we receive the correct output of
Synchronized blocks of code can also cooperate with one-another using Here’s a staggered increment from two synchronized while loops:
You may have noticed the additional conditions that have been placed around the invocations to ConclusionWe have seen the five classes pthreads packs with it ( In the meanwhile, if you have some application ideas regarding pthreads, don’t hesitate to drop them below into the comments area! Can you create threads in PHP?PHP applications can create, read, write, execute and synchronize with Threads, Workers and Threaded objects. This extension is considered unmaintained and dead. How do I make PHP multithreaded?PHP does not give inbuilt multi-threading functionality, we need to add package/extension “threads” to our PHP. Threaded Objects: A class that is a unit of executable instructions (thread), It is what you want to execute asynchronously. the run method in this class has the ability to execute it as a thread. What is a PHP thread?A thread is a small unit of instructions which can be executed by a processor. A application uses threading if it requires parallelism. In other words by a single program ,we can process multiple unit of instructions parallaly. Can we use multithreading in PHP?PHP applications, undoubtedly work effectively with multithreading capabilities. Multithreading is something similar to multitasking, but it enables to process multiple jobs at one time, rather than on multiple processes. |