Swoole Coroutine Go and Co Methods

Go and Co

Go can be used to create new coroutine which is the short name of Swoole\Coroutine::create. Co is the short name of \Swoole\Coroutine.

Create coroutine

<?php
go(function () {
    co::sleep(0.5);
    echo "hello";
});
go("test");
go([$object, "method"]);

Channels communication

<?php
$c = new chan(1);
$c->push($data);
$c->pop();

Sleep in Coroutine

<?php
Swoole\Coroutine::sleep(100);

Read file

<?php
Swoole\Coroutine::fread($fp);

Get host name

<?php
Swoole\Coroutine::gethostbyname('www.google.com');
Swoole\Coroutine::dnsLookup(string $host) : string

Get the IP address of a hostname.

Example:

<?php
$ip = Swoole\Coroutine::dnsLookup('www.google.com', 0.5);
Swoole\Coroutine::set(array $option) : void

Avaible options for Swoole\Coroutine:

<?php
$option = [
    'max_coroutine' => 4096,
    'c_stack_size' => 2 * 1024 * 1024,
    'socket_connect_timeout' => 1,
    'socket_timeout' => -1,
    'socket_read_timeout' => -1,
    'socket_write_timeout' => -1,
    'log_level' => SWOOLE_LOG_INFO,
    'hook_flags' => HOOK_FLAGS,
    'trace_flags' => '',
    'dns_cache_expire' => 60,
    'dns_cache_capacity' => 1000,
    'dns_server' => '8.8.8.8',
    'display_errors' => '',
    'aio_core_worker_num' => 10,
    'aio_worker_num' => 10,
    'aio_max_wait_time' => 1,
    'aio_max_idle_time' => 1

];
Swoole\Coroutine::set($option);
HOOK FLAGS:
SWOOLE_HOOK_TCP
SWOOLE_HOOK_UDP
SWOOLE_HOOK_UNIX
SWOOLE_HOOK_UDG
SWOOLE_HOOK_FILE
SWOOLE_HOOK_SLEEP
SWOOLE_HOOK_PROC
SWOOLE_HOOK_SSL
SWOOLE_HOOK_TLS
SWOOLE_HOOK_STREAM_FUNCTION
SWOOLE_HOOK_CURL
SWOOLE_HOOK_BLOCKING_FUNCTION
SWOOLE_HOOK_CURL
LOG_LEVELS:
SWOOLE_LOG_DEBUG
SWOOLE_LOG_TRACE
SWOOLE_LOG_INFO
SWOOLE_LOG_NOTICE
SWOOLE_LOG_WARNING
SWOOLE_LOG_ERROR
Swoole\Coroutine::getCid() : int
Swoole\Coroutine::getuid() : int

Get the ID of current Coroutine ID.

<?php
echo Swoole\Coroutine::getCid();
Swoole\Coroutine::getPcid(int $cid = null) : int

Get the parent Coroutine ID of current coroutine.

<?php
echo Swoole\Coroutine::getPcid();
Swoole\Coroutine::exists(int $cid = null) : int

Check if the coroutine exists.

<?php
echo Swoole\Coroutine::exists(Swoole\Coroutine::getCid());
Swoole\Coroutine::getContext(int $cid = null) : int

Get the context of the coroutine.

<?php

$context = new Swoole\Coroutine\Context();
var_dump($context);
Swoole\Coroutine::enableScheduler() : mixed

Enable preemptive scheduler for CPU heavy application. It is the same as ini_set("swoole.enable_preemptive_scheduler", "1"); .

Swoole\Coroutine::disableScheduler() : mixed

Disable preemptive scheduler for CPU heavy application. It is the same as ini_set("swoole.enable_preemptive_scheduler", "0"); .

Swoole\Coroutine::yield() : mixed

Give the right to execute to other coroutines.

Swoole\Coroutine::resume() : mixed

Give the right to execute to the current coroutine.

Swoole\Coroutine::create(callable $func, mixed $params = null)

Create a new coroutine and execute it immediately.

Example of using \go to create new coroutine:

<?php
go(function () {
    $db = new Co\MySQL();
    $server = array(
        'host' => '127.0.0.1',
        'user' => 'root',
        'password' => 'root',
        'database' => 'test',
    );

    $db->connect($server);

    $result = $db->query('SELECT * FROM userinfo WHERE id = 3');
    var_dump($result);
});
Execution order:
<?php
go(function() {
    go(function () {
        co::sleep(3.0);
        go(function () {
            co::sleep(2.0);
            echo "co[3] end\n";
        });
        echo "co[2] end\n";
    });

    co::sleep(1.0);
    echo "co[1] end\n";
});
Execution cost

Each coroutine use 8KB memory stack to store variables by default in PHP7.2+ or 256KB stack in <= PHP7.1.

Swoole\Coroutine::resume(string $coroutineId) : void

Resume the coroutine and continue execute the coroutine.

Example:

<?php
use Swoole\Coroutine as co;
$id = go(function(){
    $id = co::getUid();
    echo "start coro $id\n";
    co::suspend();
    echo "resume coro $id @1\n";
    co::suspend();
    echo "resume coro $id @2\n";
});
echo "start to resume $id @1\n";
co::resume($id);
echo "start to resume $id @2\n";
co::resume($id);
echo "main\n";
Swoole\Coroutine::defer(callable $func)

Execute the deferred function when the current coroutine is exiting.

Example:

<?php

function task()
{
    echo '3' . PHP_EOL;
}

Swoole\Coroutine\run(function () {
    go(function () {
        echo '1' . PHP_EOL;
        Swoole\Coroutine::defer('task');
        echo '2' . PHP_EOL;
    });
});
Swoole\Coroutine::suspend() : void

Suspend current coroutine.

Swoole\Coroutine::fread(resource $handle, int $length = 0) : string

Read files with coroutine.

Example:

<?php
$fp = fopen(__DIR__ . "/defer_client.php", "r");
Co\run(function () use ($fp) {
    fseek($fp, 256);
    $r =  Swoole\Coroutine::fread($fp);
    var_dump($r);
});
Swoole\Coroutine::fgets(resource $handle) : string

Read files line by line with coroutine.

Example:

<?php
$fp = fopen(__DIR__ . "/defer_client.php", "r");
go(function () use ($fp) {
    $r = Swoole\Coroutine::fgets($fp);
    var_dump($r);
});
Swoole\Coroutine::fwrite(resource $handle, string $string, int $length = 0) : int

Write to the file with coroutine.

Example:

<?php
$fp = fopen(__DIR__ . "/test.data", "a+");
Co\run(function () use ($fp) {
    $r =  Swoole\Coroutine::fwrite($fp, "hello world\n", 5);
    var_dump($r);
});
Swoole\Coroutine::sleep(float $seconds) : int

Sleep in coroutine and release the CPU for other operations.

Example:

<?php
$server = new Swoole\Http\Server("127.0.0.1", 9502);

$server->on('Request', function($request, $response) {
    Swoole\Coroutine::sleep(0.2);
    $response->end("<h1>Hello Swoole!</h1>");
});

$server->start();
Swoole\Coroutine::gethostbyname(string $domain, int $family = AF_INET): string

Get the IP from host name.

Example:

<?php
use Swoole\Coroutine as co;
$ip = co::gethostbyname("www.google.com");
Swoole\Coroutine::getaddrinfo(string $domain, int $family = AF_INET, int $socktype = SOCK_STREAM, int $protocol = IPPROTO_TCP, string $service = null): array | bool

Exmple:

<?php
$array = co::getaddrinfo("www.google.com");
Swoole\Coroutine::exec(string $cmd) : array

Execute shell command with coroutine.

Example:

<?php
go(function() {
    $ret = Co::exec("md5sum ".__FILE__);
});
Swoole\Coroutine::readFile(string $filename) : string

Read file with coroutine.

Example:

<?php
use Swoole\Coroutine as co;
$filename = __DIR__ . "/defer_client.php";
co::create(function () use ($filename) {
    $r =  co::readFile($filename);
    var_dump($r);
});
Swoole\Coroutine::writeFile(string $filename, string $fileContent, int $flags)

Write file with coroutine.

<?php
use Swoole\Coroutine as co;
$filename = __DIR__ . "/defer_client.php";
co::create(function () use ($filename) {
    $r = co::writeFile($filename,"hello swoole!");
    var_dump($r);
});
Swoole\Coroutine::stats() : array

Get the current status of coroutine.

Example:

<?php
var_dump(Swoole\Coroutine::stats());

array(1) {
  ["coroutine_num"]=>
  int(132)
  ["coroutine_peak_num"]=>
  int(2)
}
Swoole\Coroutine::getBackTrace(int $cid=0, int $options=DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit=0) : array

Get call stack of the function.

Example:

<?php
function test1() {
    test2();
}

function test2() {
    while(true) {
        co::sleep(10);
        echo __FUNCTION__." \n";
    }
}

$cid = go(function () {
    test1();
});

go(function () use ($cid) {
    while(true) {
        echo "BackTrace[$cid]:\n-----------------------------------------------\n";
        var_dump(co::getBackTrace($cid))."\n";
        co::sleep(3);
    }
});
Swoole\Coroutine::list() : Iterator

Get all the coroutines of current process.

Example:

<?php
$coros = Swoole\Coroutine::list();
foreach($coros as $cid)
{
    var_dump(Coroutine::getBackTrace($cid));
}
Runtime::enableCoroutine

Since version 4.1.0, it is possible to enable coroutine on any IO libraries using php_stream.

Support libraries:

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

Not support:

  • MySQL with libmysqlclient
  • CURL with libcurl
  • MongoDB with mongo-c-client
  • pdo_pgsql, pdo_ori, pdo_odbc, pdo_firebird

Example:

<?php
Swoole\Runtime::enableCoroutine();

go(function () {
    $redis = new redis;
    $retval = $redis->connect("127.0.0.1", 6379);
    var_dump($retval, $redis->getLastError());
    var_dump($redis->get("key"));
    var_dump($redis->set("key", "value2"));
    var_dump($redis->get("key"));
    $redis->close();
});