2024 年 PHP 日本大会

GearmanClient::addTask

(PECL gearman >= 0.5.0)

GearmanClient::addTask添加一个要并行运行的任务

描述

public GearmanClient::addTask(
    string $function_name,
    string|int|float $workload,
    mixed $context = null,
    ?string $unique_key = null
): GearmanTask|false

添加一个要与其他任务并行运行的任务。为所有要并行运行的任务调用此方法,然后调用GearmanClient::runTasks() 来执行工作。请注意,需要有足够的 worker 可用才能使所有任务并行运行。

参数

function_name

worker 要执行的已注册函数

workload

要处理的序列化数据

context

与任务关联的应用程序上下文

unique_key

用于标识特定任务的唯一 ID

返回值

一个 GearmanTask 对象,如果任务无法添加,则返回 false

范例

示例 #1 提交两个任务的基本示例

<?php

# 创建我们的 gearman 客户端
$gmclient= new GearmanClient();

# 添加默认作业服务器
$gmclient->addServer();

# 设置一个函数,在工作完成后调用
$gmclient->setCompleteCallback("complete");

# 添加一个任务,对字符串 "Hello World!" 执行 "reverse" 函数
$gmclient->addTask("reverse", "Hello World!", null, "1");

# 添加另一个任务,对字符串 "!dlroW olleH" 执行 "reverse" 函数
$gmclient->addTask("reverse", "!dlroW olleH", null, "2");

# 运行任务
$gmclient->runTasks();

function
complete($task)
{
print
"COMPLETE: " . $task->unique() . ", " . $task->data() . "\n";
}

?>

以上示例将输出类似以下内容

COMPLETE: 2, Hello World!
COMPLETE: 1, !dlroW olleH

示例 #2 传递应用程序上下文提交两个任务的基本示例

<?php

$client
= new GearmanClient();
$client->addServer();

# 设置一个函数,在工作完成后调用
$client->setCompleteCallback("reverse_complete");

# 添加一些任务作为放置结果的占位符
$results = array();
$client->addTask("reverse", "Hello World!", $results, "t1");
$client->addTask("reverse", "!dlroW olleH", $results, "t2");

$client->runTasks();

# 结果现在应该从回调中填充
foreach ($results as $id => $result)
echo
$id . ": " . $result['handle'] . ", " . $result['data'] . "\n";


function
reverse_complete($task, $results)
{
$results[$task->unique()] = array("handle"=>$task->jobHandle(), "data"=>$task->data());
}

?>

以上示例将输出类似以下内容

t2: H.foo:21, Hello World!
t1: H:foo:22, !dlroW olleH

参见

添加注释

用户贡献的注释 3 条注释

7
liv_romania at yahoo dot com
9 年前
在PHP 5.5中,可以使用以下代码通过引用传递上下文,避免“Call-time pass-by-reference has been removed”错误。

<?php
$client
= new GearmanClient();
$client->addServer();

# 设置工作完成时调用的函数
$client->setCompleteCallback("reverse_complete");

# 使用StdClass代替数组
$results = new StdClass();
$results->value = array();

# 添加一些任务作为结果的占位符
$client->addTask("reverse", "Hello World!", $results, "t1");
$client->addTask("reverse", "!dlroW olleH", $results, "t2");

$client->runTasks();

# 结果现在应该从回调函数中填充
foreach ($results->value as $id => $result) {
echo
$id . ": " . $result['handle'] . ", " . $result['data'] . "\n";
}

function
reverse_complete(GearmanTask $task, StdClass $results)
{
$results->value[$task->unique()] = array(
"handle" => $task->jobHandle(),
"data" => $task->data()
);
}
?>
1
[email protected]
10年前
注意,如果要分别运行多个任务,参数`$unique`必须不同。如果多个任务的`$unique`参数相同,您将得到相同的任务。

<?php
$unique
=1;

$gclient = GearmanClient();
$gclient->addServer('srv');

$this->setCreatedCallback(function(GearmanTask $task) {
print
$task->jobHandle() . "\n";
});

$gclient->addTask('function_name', 'workload', null, $unique);
$gclient->addTask('function_name', 'workload', null, $unique);
$gclient->addTask('function_name', 'workload', null, $unique);
$gclient->runTasks();

sleep(5);
?>

这段脚本只会打印一个句柄。

H:srv:377382343
H:srv:377382343
H:srv:377382343
0
Jeremy Zerr
11年前
从PHP 5.3.0开始,当您在`$client->addTask(..., ..., &$results, ...);`中使用`&`时,会收到“call-time pass-by-reference”已弃用的警告。从PHP 5.4.0开始,call-time pass-by-reference已被移除,因此使用它将引发致命错误。

这意味着,当您像上面的示例那样,使用上下文参数调用addTask时

<?php
# 添加一些任务作为结果的占位符
$results = array();
$client->addTask("reverse", "Hello World!", &$results, "t1");
?>

您将收到此“call-time pass-by-reference”警告(或错误)。通过将上下文变量更改为对象,可以避免这种情况,并仍然获得功能性代码,如下所示:

<?php
$results
= new \stdClass();
$client->addTask("reverse", "Hello World!", $results, "t1");
?>

然后,为了完整性,更改完成处理程序以期望引用。

<?php
function reverse_complete($task, &$results) { ... }
?>

然后在完成处理程序内,您可以使用`$results`对象保存结果,以便在完成处理程序外部访问。
To Top