Coroutine features are mature in Open Swoole since version 4.x. Swoole provides the powerful CSP (Communicating sequential processes) programming model with three keywords: go
, chan
, defer
.
CSP is an alternative concurrent programming model to the actor model in Erlang
or Akka
. It is well known because it is adopted in Golang
. The key concepts of CSP are:
processes
channels
alternation
Version used in this article: Swoole 4.2.9 PHP 7.2.9
go
, Create a new coroutinechan
, Create a new channel for message-passingdefer
, Delay the task until the exit of the coroutine, FIFOThere is no I/O waste within these three keywords. It is as fast as use Array in PHP. Compare with socket
or file
operations which are blocking the I/O, these three keywords are very fast and cheap.
The keyword go
creates a new coroutine for a function, then the function is running concurrently. If you like to concurrently run a piece of code, just have to put the function into a go
wrapper.
Result
The function test2
is running after test1
. So the whole script needs three seconds to be finished.
Now let's see the magic of go
, we can put the above test1
and test2
function into go()
.
Swoole\Runtime::enableCoroutine()
switch the PHP build-instream
,sleep
,pdo
,mysqli
,redis
from blocking model to be async model with Swoole Coroutine.
Result
We can see the whole script only takes 2 seconds which is the time cost of function test2
.
Time cost for sequential processing vs concurrent processing
It is easy to write concurrent programs with go
feature in Open Swoole. The problem we are facing now is how this coroutine collaborates with each other.
Channel
can be created in Open Swoole for exchanging data between different coroutines.
A channel is created by keyword chan
, you are able to choose the size of the channel:
There are two methods can be used to operate the chan
:
Let's see a real-world use case: concurrently fetch two web pages https://www.google.com and https://www.bing.com. Keep it simple we only fetch the status code of HTTP responses:
Result
We have created three coroutine
with the keyword go
. The first one is trying to get the final result from the other two task
coroutines. We used chan
for the communication between these three coroutines:
Once Coroutine 1 gets the result from the other two, the process will go to the next step and exit the script.
defer
defer
can be used to do some final tasks when coroutines finished the task. Similar to register_shutdown_function
in PHP.
Result
We can see the sequence of the results: a,b,c then the last deferred task ~b, finally the first deferred task ~a.
More about defer
, please check Coroutine in Open Swoole 4.x vs Coroutine in Golang
Go, Chan and Defer are provided since Open Swoole 4.x, it provides a brand new programming model in PHP: CSP. It can be used for writing TCP Server
, UDP Server
, HTTP Server
with PHP language or PHP CLI
scripts and speed up the tasking related to I/O.
Join 4,000+ others and never miss out on new tips, tutorials, and more.