swoole_server->task

投递一个异步任务到task_worker池中。此函数会立即返回。worker进程可以继续处理新的请求。

bool swoole_server::task(mixed $data, int $dst_worker_id = -1) 
$task_id = $serv->task("some data");

例子:task实现db pool

<?php
$serv = new swoole_server("127.0.0.1", 9500);
$serv->set(array(
    'worker_num' => 1,
    'task_worker_num' => 8, //database connection pool
    'db_uri' => 'mysql:host=127.0.0.1;dbname=test',
    'db_user' => 'root',
    'db_passwd' => 'root',
//    'task_worker_max'=>100
));
function my_onReceive($serv, $fd, $from_id, $data)
{
    $result = $serv->taskwait($data);
    if ($result !== false) {
        list($status, $db_res) = explode(':', $result, 2); 
        if ($status == 'OK') {
            $serv->send($fd, var_export(unserialize($db_res), true) . "\n");
        } else {
            $serv->send($fd, $db_res);
        }   
        return;
    } else {
        $serv->send($fd, "Error. Task timeout\n");
    }   
}
function my_onTask($serv, $task_id, $from_id, $sql)
{
    static $link = null;
    if ($link == null)
    {
        $link = new PDO($serv->setting['db_uri'], $serv->setting['db_user'], $serv->setting['db_passwd']);
        if (!$link)
        {
            $link = null;
            $serv->finish("ER: connect database failed.");
            return;
        }
    }
    $result = $link->query($sql);
    if (!$result)
    {
        $serv->finish("ER: query error");
        return;
    }
    $data = $result->fetchAll();
    $serv->finish("OK:" . serialize($data));
}
function my_onFinish($serv, $data)
{
    echo "AsyncTask Finish:Connect.PID=" . posix_getpid() . PHP_EOL;
}
$serv->on('Receive', 'my_onReceive');
$serv->on('Task', 'my_onTask');
$serv->on('Finish', 'my_onFinish');
$serv->start();

$dst_worker_id在1.6.11+后可用,默认为随机投递
$task_id是从0-42亿的整数,在当前进程内是唯一的
task方法不能在task进程中调用

此功能用于将慢速的任务异步地去执行,比如一个聊天室服务器,可以用它来进行发送广播。 当任务完成时,在task进程中调用$serv->finish("finish") 告诉worker进程此任务已完成。当然swoole_server->finish是可选的。

task底层使用Unix Socket管道通信,是全内存的,没有IO消耗。单进程读写性能可达100万/s,不同的进程使用不同的管道通信,可以最大化利用多核。

AsyncTask功能在1.6.4版本增加,默认不启动task功能,需要在手工设置task_worker_num来启动此功能
task_worker的数量在swoole_server::set参数中调整,如task_worker_num => 64,表示启动64个进程来接收异步任务
swoole_server_task和swoole_server_finish在版本swoole-1.7.16-stable发送$data的长度可以超过8K, 此参数受SW_BUFFER_SIZE宏控制 。超过8k的数据默认是用/tmp作为临时存储

配置参数

swoole_server->task/taskwait/finish 3个方法当传入的$data数据超过8K时会启用临时文件来保存。当临时文件内容超过 server->package_max_length 时底层会抛出一个警告。

WARN: task package is too big.

server->package_max_length 默认为2M

注意事项