Swoole Coroutine

Version: PHP: 7.1+ and Swoole: 4.4.0+

Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing multiple entry points for suspending and resuming execution at certain locations.

It is a purely user-mode thread. Compare with thread or process, all the operations in coroutines are happening in user mode, so the cost to create or switch coroutines are cheaper.

Swoole creates one coroutine for each request to the server, switches coroutines based on IO status.

The advantages of Swoole coroutines are:

  • Developers can use sync programming style to archive the performance of async IO. Avoiding callback or multiple level callbacks in codes.
  • Compare with coroutines in PHP language, yield is not for IO switching. It is more convenient.

Methods

  • Swoole\Coroutine::create
  • Swoole\Coroutine::set
  • Swoole\Coroutine::dnsLookup
  • Swoole\Coroutine::getCid
  • Swoole\Coroutine::getPcid
  • Swoole\Coroutine::exists
  • Swoole\Coroutine::getElapsed
  • Swoole\Coroutine::getContext
  • Swoole\Coroutine::enableScheduler
  • Swoole\Coroutine::disableScheduler
  • Swoole\Coroutine::yield
  • Swoole\Coroutine::resume
  • Swoole\Coroutine::defer
  • Swoole\Coroutine::suspend
  • Swoole\Coroutine::sleep
  • Swoole\Coroutine::gethostbyname
  • Swoole\Coroutine::getaddrinfo
  • Swoole\Coroutine::exec
  • Swoole\Coroutine::readFile
  • Swoole\Coroutine::writeFile
  • Swoole\Coroutine::stats
  • Swoole\Coroutine::getBackTrace
  • Swoole\Coroutine::list
  • Swoole\Coroutine::enableCoroutine

    Example

    <?php
    Co\run(function() {
        go(function() {
            Co::sleep(1);
            echo "Done 1\n";
        });
        go(function() {
            Co::sleep(1);
            echo "Done 2\n";
        });
    });
    

    Create or use a coroutine execution context

    Coroutines must be executed within a coroutine context.

    A coroutine context is created with the callback function: request, receive, connect in a Swoole\Server or Swoole\HTTP\Server.

    You can also create a coroutine context with Co\Run.

    Sync coroutines with Channel or WaitGroup

    Channels are used for the communication between coroutines.

    Use coroutine clients and function within a coroutine context

    You can use the following coroutine clients within a coroutine context:

    Enable coroutine on the libraries with Hook flags:

    Swoole Runtime HOOK Flags

    • Redis
    • mysqlnd PDO, mysqli
    • SOAP
    • file_get_contents, fopen
    • stream_socket_client
    • fsockopen

    Other

    Important Configuration

    max_coro_num: The max number of coroutine created by the Swoole server. The default value is 3000.

    Notices

    • Global variables: static global variables may change during coroutine switching.
    • Xdebug, xhprof, Blackfire can't be used for code profiling.

    Why coroutine is important for concurrency

    Think about the situation when you want to get some data from both the Redis Server, and MySQL server.

    The normal process is: Redis send data->redis receive data->mysql send data->mysql receive data.

    The time cost of the above process is the IO time of Redis + IO time of MySQL.

    With coroutine clients, we can reduce the latency: Redis send data/MySQL send data->redis receive data/MySQL receive data.

    The time cost of the process is the max IO time of Redis and MySQL.

    setDefer can be used to delay the receive operation.