在 PHP7 pthreads 扩展中使用 Pool 类

2023-12-04

我做了 pthreads PHP7 扩展的最基本的演示,它使用Pool类(这个演示https://github.com/krakjoe/pthreads#polyfill)并稍微扩展它,这样我就可以从线程中获取结果(或者至少我认为我可以):

$pool = new Pool(4);

foreach (range(1, 8) as $i) {
    $pool->submit(new class($i) extends Threaded
    {
        public $i;
        private $garbage = false;

        public function __construct($i)
        {
            $this->i = $i;
        }

        public function run()
        {
            echo "Hello World\n";
            $this->result = $this->i * 2;
            $this->garbage = true;
        }

        public function isGarbage() : bool
        {
            return $this->garbage;
        }
    });
}

while ($pool->collect(function(Collectable $task) {
    if ($task->isGarbage()) {
        echo $task->i . ' ' . $task->result . "\n";
    }
    return $task->isGarbage();
})) continue;

$pool->shutdown();

让我感到困惑的是,它有时无法获得所有任务的结果:

Hello World
Hello World
Hello World
Hello World
Hello World
1 2
2 4
Hello World
Hello World
3 6
Hello World
7 14
4 8
8 16

现在有两行5 10 and 6 12失踪了,但我不明白为什么。这种情况仅有时发生(可能是 1/10 次运行)。

看起来原始演示是针对旧版本的pthreads因为有Collectable现在自动实现的接口Threaded如果我没错的话。

然后自述文件说:

Pool::collect 机制从 Pool 转移到 Worker,以获得更健壮的 Worker 和更简单的 Pool 继承。

所以我想我做错了什么。

Edit: 我举的例子是Pool::collect 是如何工作的?并更新它以使用最新的 pthreads 和当前的 PHP7,但结果是相同的。看起来它无法从最后执行的线程收集结果。

$pool = new Pool(4);

while (@$i++<10) {
    $pool->submit(new class($i) extends Thread implements Collectable {
        public $id;
        private $garbage;

        public function __construct($id) {
            $this->id = $id;
        }

        public function run() {
            sleep(1);
            printf(
                "Hello World from %d\n", $this->id);
            $this->setGarbage();
        }

        public function setGarbage() {
            $this->garbage = true;
        }

        public function isGarbage(): bool {
            return $this->garbage;
        }

    });
}

while ($pool->collect(function(Collectable $work){
    printf(
        "Collecting %d\n", $work->id);
    return $work->isGarbage();
})) continue;

$pool->shutdown();

这输出以下内容,显然没有收集所有线程:

Hello World from 1
Collecting 1
Hello World from 2
Collecting 2
Hello World from 3
Collecting 3
Hello World from 4
Collecting 4
Hello World from 5
Collecting 5
Hello World from 6
Hello World from 7
Collecting 6
Collecting 7
Hello World from 8
Hello World from 9
Hello World from 10

正如您非常正确地指出的那样,您复制的代码针对 pthreads v2(适用于 PHP 5.x)。

问题归结为 pthread 中的垃圾收集器不是确定性的。这意味着它的行为无法预测,因此无法可靠地使用它来从池已执行的任务中获取数据。

获取此数据的一种方法是传入Threaded对象放入正在提交到池中的任务中:

<?php

$pool = new Pool(4);
$data = [];

foreach (range(1, 8) as $i) {
    $dataN = new Threaded();
    $dataN->i = $i;

    $data[] = $dataN;

    $pool->submit(new class($dataN) extends Threaded {
        public $data;

        public function __construct($data)
        {
            $this->data = $data;
        }

        public function run()
        {
            echo "Hello World\n";
            $this->data->i *= 2;
        }
    });
}

while ($pool->collect());

$pool->shutdown();

foreach ($data as $dataN) {
    var_dump($dataN->i);
}

上面的代码有几点需要注意:

  • Collectable(现在是 pthreads v3 中的一个接口)由Threaded类已经存在,所以不需要自己实现。
  • 一旦任务被提交到池中,它就已经被认为是垃圾,因此不需要自己处理这部分。虽然您仍然可以覆盖默认的垃圾收集器,但在绝大多数情况下(包括您的情况)不需要这样做。
  • 我仍然调用collect方法(在阻塞主线程的循环中,直到所有任务执行完毕),以便在池执行任务时可以对任务进行垃圾收集(使用 pthread 的默认收集器)以释放内存。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 PHP7 pthreads 扩展中使用 Pool 类 的相关文章

  • 使用 Laravel 4 验证多个文件上传

    如何在 Laravel 4 中验证上传文件的数组 我已将其设置为允许多个文件 并且已测试这些文件是否存在于 Input file files 数组中 但如何验证每个文件呢 这是我尝试过的 notesData array date gt In
  • 让登录更安全

    我已使用此代码进行管理员登录 仅当用户输入正确的用户名和密码时才应打开loginhome php 但后来我意识到这根本不安全 任何人都可以直接访问 mywebsite loginhome php 而无需登录 注销后 可以使用后退按钮打开 l
  • Zend Framework 生成唯一的字符串

    我想生成一个唯一的 4 6 个字符长的字母数字字符串 以便与每个记录 用户 一起保存在数据库中 db 字段具有唯一索引 因此尝试保存预先存在的字符串会生成错误 现在我正在生成一个随机字符串并使用 try catch 因此在添加新记录时如果抛
  • PHP 如何判断用户是否按下了 Enter 键或 Submit 按钮?

    我遇到的问题是我在一个表单中有多个提交输入 每个提交输入都有不同的值 我更愿意将它们保留为提交 Whenever the user presses Enter it is as though the topmost submit input
  • 搜索引擎如何找到相关内容? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Google 在解析网络时如何找到相关内容 例如 Google 使用 PHP 原生 DOM 库来解析内
  • MySQL/PDO::quote() 尽管使用 PDO::PARAM_INT 参数,但仍在整数周围加上引号

    无论我传递给什么值 数据类型对 它都会出现 pdo gt quote value type 它总是将其引用为字符串 echo pdo gt quote foo PDO PARAM STR foo as expected echo pdo g
  • Yii 使用 ajax 进行分页

    我需要使用ajax启用分页 我的代码 控制器 更新内容ajax function actionIndex dataProvider new CActiveDataProvider News array pagination gt array
  • FPDI/FPDF:水印和打印多页

    我修改了这个堆栈问题 当用户尝试下载文件时在 pdf 文件上应用水印 https stackoverflow com questions 3983432 applying watermarks on pdf files when users
  • PHP严格标准:声明应该兼容

    我有以下类层次结构 class O Base class O extends O Base abstract class A Abstract public function save O Base obj class A extends
  • Symfony2 Assetic 和 Less Sourcemaps

    我不确定如何破解 assetic less 过滤器以输出源映射文件 我这里指的是LessFilterhttps github com kriswallsmith assetic blob master src Assetic Filter
  • 从 .phar 存档中提取文件

    对于 Phar 文件 我完全错过了一些东西 我正在安装一个需要 phpunit pdepend 和其他依赖项的项目 我将它们作为 phar 文件获取 但是 我无法使用命令行工具 php 命令 从中提取文件 我用谷歌搜索了这个问题 但没有发现
  • 在 PHP 中撤销 Google 访问令牌

    正如标题所示 我想以编程方式撤销授予的访问令牌 即在 PHP 中 我发现这个他们的网站 https developers google com identity protocols OAuth2WebServer tokenrevoke 但
  • 在 PHP 中使用 phpseclib 时出现 RSA 问题

    我正在尝试在 phpseclib 中使用 RSA 实现 我认为在函数中执行一次代码并重新使用该函数会更容易 当我尝试向代码发送短信时 我收到一条错误消息 提示 解密错误 测试还让我意识到每次代码运行时密文都是不同的 所以我显然在那里做错了什
  • 在 Wordpress 站点中进行 AJAX 调用时出现问题

    我在使用 Wordpress 站点功能的 AJAX 部分时遇到了一些问题 该功能接受在表单上输入的邮政编码 使用 PHP 函数来查找邮政编码是否引用特定位置并返回到该位置的永久链接 我的第一个问题是关于我构建的表单 现在我的表单操作是空白的
  • PHP preg_filter 返回意外的长值

    尝试在 Woocommerce 中删除标签并过滤值 但无法以正确的格式获取它 有东西有腥味 我正在使用WC gt cart gt get cart subtotal 来检索该值 在此示例中 我的值是 2 429kr 原始返回值是 span
  • 表单提交后如何保留选择字段中的选定值?

    我有一个用于将票证上传到数据库的主页 我有一个选择字段 我想保留用户在提交表单之前选择的值 但它没有发生 这是我选择字段的代码
  • Laravel 中只向登录用户显示按钮

    如果我以 John 身份登录 如何才能只显示 John 的红色按钮而不显示 Susan 的红色按钮 测试系统环境 Win10 Laravel5 4 Mysql5 7 19 table class table table responsive
  • 如何在 Laravel 中使用 PUT http 动词提交表单

    我知道这个问题可能已经提出 但我就是无法让它发挥作用 如果有人可以帮助我 我将非常感激 我安装了 colletive form 但答案也可以是 html 表单标签 现在列出我的表格 我的路线和我的例外情况 Form model array
  • 为什么 Composer 降级了我的包?

    php composer phar update这样做了 删除了 2 3 0 软件包并安装了整个 2 2 5 Zend Framework php composer phar update Loading composer reposito
  • 对具有混合类型值的数组进行数字排序

    我有一个像这样的混合数组 fruits array lemon Lemon 20 banana apple 121 40 50 然后申请sort 其功能如下 sort fruits SORT NUMERIC foreach fruits a

随机推荐