Categories
PHP

Generators and Coroutines in PHP

If you’re a nerd and would love a very detailed post on Coroutines, here’s one for you – http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html. If you decide to read the above mentioned article, I believe you can safely skip my article below, it doesn’t have anything extra, rather it tries to explain co-routines on a rush.

NOTE: The features of PHP described in this post were introduced on PHP 5.5.0. If you are using an older version, this is not going to work. Please upgrade your PHP version and enjoy the performance bonus with these awesome new additions! 🙂

Before we can start on Coroutines, let’s review our knowledge on Generators. Generators allow us to quickly create iterators which instead of populating a large dataset once, populate each item in turn, one after another. Since one item is produced/returned every turn, it is very memory efficient. In fact you can handle an unlimited stream of data with minimal memory usages using iterators. Let’s see a quick example:

So what does it do? The gen() function returns an iterator of the “Generator” class. (If you look at the manual, Generator class implements the “Iterator” interface and thus we can use foreach on the class).

Internally, when we iterate over the generator object, it starts executing the gen() function. When it hits the yield statement, it pauses execution of the function and returns the value to the generator object (and thus back to our main loop). We then print the value. In the next iteration, the gen() function is resumed from where it was paused and executed until it hits the yield statement again.

Let’s see an example of generator which doesn’t use any loops inside and rather has multiple yield statements. This should help us in better understanding the use of yield in generators.

The above example should explain better how Generators are actually interruptible functions which can be paused and resumed with the yield statement to make iteration possible on the returned values. Now, as long as Generators are concerned, the function returns value. This is a one way communication. But what if we want to send back a value to the function? Coroutines come into play. Coroutines allow two way communication through the “send()” method on a “Generator” class. When we send a value back to the function, yield switches it’s role. Instead of returning a value back to the iteration process, it then receives the value we send into the function. A very plain example to describe this:

What’s happening here? We’re sending a value back and the value is available to the “yield” statement inside the function.

We can return and receive values with the same yield statement. Let’s see how:

Awesome no? Well, Coroutines are definitely complex and sometimes very hard to handle. If you don’t get the concepts at the first look or would love to understand more of the internal implementation, I recommend you read and understand the article I mentioned at the beginning. And do play with it. Have fun!

Categories
PHP

Multithreading in PHP: Doing it right!

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 –

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!

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:

Okay, so looks like it worked. No?

Here’s some helpful links:

Github Repo: https://github.com/krakjoe/pthreads

Manual: http://docs.php.net/manual/en/book.pthreads.php

Categories
Bangla PHP Screencast

Object Oriented Programming in PHP

Please provide your valuable feedback in the comments section and share the video with others. Your feedback keeps me motivated and helps me improve the quality.

The video is available in HD (720p max)