Long ago I wrote a similar post on multi threading in php – http://www.masnun.com/2009/09/07/php-multi-threading.html – which allowed us to fork a new process and execute codes in parallel. While it often served the purpose right, it was not true multi-threading.
I have come across the awesome “pthreads” PECL extension for some time. Tonight, I planned to give it a shot. What sparked my curiosity? Well, let me quote them –
this is not a hack, we don’t use forking or any other such nonsense, what you create are honest to goodness posix threads that are completely compatible with PHP and safe … this is true multi-threading 🙂
True multi-threading in PHP, isn’t that worth wasting a night’s sleep to check out?
Installation
Since it’s a PECL extension, you can just do –
1 |
pecl install pthreads |
It requires ZTS aka thread safety enabled in PHP. So if your PHP is non-zts, please make sure to recompile with zts. Please consult appropriate docs on your platform on how to do that.
If you’re on OS X and use homebrew php, you can use the “–with-thread-safety” flag to reinstall php with ZTS enabled. Now install the extension and it should work.
Let’s write some codes
Of course, here we go!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php /** * Author: Abu Ashraf Masnun * URL: http://masnun.me */ class WorkerThreads extends Thread { private $workerId; public function __construct($id) { $this->workerId = $id; } public function run() { sleep(rand(0, 3)); echo "Worker {$this->workerId} ran" . PHP_EOL; } } // Worker pool $workers = []; // Initialize and start the threads foreach (range(0, 5) as $i) { $workers[$i] = new WorkerThreads($i); $workers[$i]->start(); } // Let the threads come back foreach (range(0, 5) as $i) { $workers[$i]->join(); } |
The code is pretty straightforward. We extend the Thread class which has an abstract method – “run” which we must implement with our business logic. The codes inside this method actually get executed when the threads run. Then we create 5 instances and call the “start” method. After the threads have started, we again call the “join” method on each. This will ask our main thread to wait for the child threads to return.
As you can see, the main worker threads all output their ID, thus we can identify which one executed when. This could be helpful to determine if they were actually running in threads (and thus being async in nature) or ran one after one.
I got these outputs from several run:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
~/Codes/php ⮀ php threads.php Worker 3 ran Worker 1 ran Worker 4 ran Worker 2 ran Worker 0 ran Worker 5 ran ~/Codes/php ⮀ php threads.php Worker 4 ran Worker 2 ran Worker 3 ran Worker 1 ran Worker 5 ran Worker 0 ran ~/Codes/php ⮀ php threads.php Worker 4 ran Worker 1 ran Worker 3 ran Worker 5 ran Worker 0 ran Worker 2 ran ~/Codes/php ⮀ |
Okay, so looks like it worked. No?
Here’s some helpful links:
Github Repo: https://github.com/krakjoe/pthreads
20 replies on “Multithreading in PHP: Doing it right!”
This is amazing, nice write! You can do true threading with pthreads (http://pthreads.org). A multi-threaded web server (http://www.appserver.io) for PHP is in progress using pthreads. You can utilize this Posix threads. Thanks to Joe Watkins for creating pthreads and revitalizing PHP community.
Don’t know if you are having troubles with it.. but have you tried Pooling? I can’t find any material over internet anywhere where I could find some sample lengthy code for pooling. Strange thing is, during the normal thread procedure my threads consume about 600MB of memory and cause a lot of laod but run succesfully, but when I start pooling my tasks even a dummy script after a long list of tasks goes to segmentation fault. Did you ever try with pooling and if yes can you help me with too? Thanx in advance!
Hey,
Sorry, I didn’t try that. I usually use Python or Go for that kind of tasks.
Regards,
Masnun
What apache config will be used – prefork or worker thread.?
I don’t think the extension would play well with Apache.
[…] […]
Dear i need some help if you can.
I want to send SMS through API. I send a request and request tooks almost 1 second for 1 SMS. I want to send multiple SMS requests to API server in 1 second. Please tell me how can i do it using pthread in php.
http://stackoverflow.com/questions/28493421/send-multiple-numbers-sms-requests-in-one-second-php
i have already posted a question with code on stackoverflow. Please take a look here also.
Thanks
Use Beanstalkd and multiple workers.
I came across this comment during my many hours trying to introduce myself to the topic of parallel programming in php. Still just trying to figure out the difference between pthreads, pcntl_fork, exec, queues, etc. Can you answer a couple of questions about your last comment for me?
By multiple workers do you mean increasing the numproc config value?
are these multiple workers just forks? or POSIX?
Is there a limit to how many workers you can use?
Do you know of a good resource to help me get a better understanding of all this?
Thanks!
Good post. By the way the mentioned project appserver.io which is a fully featured application server entirely written in PHP is now available in a stable version 1.0.0. Maybe you will find some time checking it out and write a review.
Thanks
Hi Stefan,
Thanks for dropping by, I shall check it out.
Great post. Thank you.
Interesting fine. Unfortunately I no longer work with PHP and don’t have an environment setup to quickly test this.
how get variable from thread?!!!
Cool, you make a post about asynchronous php but do not know to ask questions.
You left php right?
Yes
Since, and unfortunately, multi-threading is not available in PHP I went on a search for find a solution to create multiple threads of an application.
Fatal error Class Thread not found
in php version 7.0.18 in windows
how to fix..???