在 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 类 的相关文章

  • MySql如何通过过滤多列来限制多个数字?

    我想从数据库中获取 4 个不同类别的 50 个问题 我想要 4 个不同类别中每个类别的不同数量的问题 我的结果集必须包含第一类 12 个问题 第二类 20 个问题 第三类 10 个问题和第四类 8 个问题 我的问题表中总共有 50 个问题
  • jetty服务器运行php代码

    我想配置让jetty运行PHP文件 但到目前为止还没有成功 我在 Eclipse IDE 中安装了 Jetty WTP 工具 当我启动 Jetty 服务器时 我得到了例外 java lang ClassNotFoundException o
  • 如何显示多维数组第二层的 json 值?

    解决此代码时遇到问题 这些是数组 Array 0 gt stdClass Object id gt 1 name gt delux price gt 213 description gt tv gt 0 breakfast gt 0 par
  • 我可以从匿名 PL/SQL 块向 PHP 返回值吗?

    我正在使用 PHP 和 OCI8 执行匿名 Oracle PL SQL 代码块 有没有什么方法可以让我绑定一个变量并在块完成后获取其输出 就像我以类似的方式调用存储过程时一样 SQL declare something varchar2 I
  • 如何使用 PHP 更改文件的标题属性

    用户使用我的 PHP 应用程序上传 PDF 文件 我将它们存储在 S3 上 稍后 其他用户会查看这些文件 我会在他们的浏览器中 内联 显示这些文件 问题在于 PDF 的 标题 属性显示在通常显示网站标题的浏览器选项卡中 由于它是由原始上传的
  • 如何转换为在视图上使用 Yii CDataProvider?

    我正在尝试学习 Yii 并查看了 Yii 文档 但仍然没有真正理解 我仍然不知道如何在控制器和视图上使用 CDataProvider 来显示视图上可用的所有博客文章 任何人都可以根据以下内容提供建议或举例 我的 PostController
  • PHP中特殊字符的转换

    我已经尝试了很多功能 但我根本无法弄清楚这一点 无论如何 正确的方法 在称为描述的表单字段中 我可以期待各种字符 在将它们提交到数据库之前 需要将它们格式化为 HTML 实体 现在 我的代码 formdesc htmlentities PO
  • PHP:file_get_contents 与 json_decode 不能一起工作

    使用 file get contents 读取 json 文件后遇到问题 当我运行这段代码时 它工作正常
  • 如何将日期/时间从 24 小时格式转换为 12 小时 AM/PM? [复制]

    这个问题在这里已经有答案了 我从数据源中获取以下格式的日期和时间 19 24 15 06 13 2013 我需要将其转换为 12 小时 AM PM 格式 不带秒 所以上面的时间是晚上 7 24 日期应保留为 mm dd yyyy 格式 在
  • 如何在 Cakephp 3 中创建按字段集分组的多个复选框

    我在阅读本文档时遇到问题 Cakephp3 Cookbook 表单 创建选择选择器 http book cakephp org 3 0 en views helpers form html creating select pickers我尝
  • 执行数组内的函数

    是否可以从数组内部执行匿名函数 也在数组内部定义 return execute function logic 或者我应该在外面定义它然后再调用它 从技术上讲 您可以将该函数括在括号中并像这样调用它 return function retur
  • Yii 框架:控制器/操作 url 和参数

    在我的申请中 我有ApiController with actionUsers 所以在 YII 中路径变成api users 现在为了获取某些用户信息 我使用以下路径api users id 10其中 10 是用户 ID id路径的一部分基
  • PHP Netbeans:xdebug 在每个 include() 或 require() 上停止

    我刚刚发现使用 netbeans IDE 中集成的 xdebug 进行 PHP 调试 我认为这很棒 没有它我怎么生活 但有一个问题 如果我在代码深处设置了一个断点 我必须在到达断点之前多次按 继续 F5 因为脚本会在每个 include 和
  • PHP 5 的 SQLite 编译设置是什么?

    SQLite 3 7 附带了新的预写日志记录 WAL http www sqlite org wal html并且有很多设置可以被配置 http www sqlite org compile html 但是 似乎没有任何方法可以改变任何事情
  • PDO fetch() 失败时会抛出异常吗?

    有没有方法PDO语句 fetch http php net manual en pdostatement fetch php如果 PDO 错误报告系统设置为抛出异常 则在失败时抛出异常 例如 如果我设置 PDO ATTR ERRMODE g
  • 在mysql中搜索“SanF”时获取旧金山的记录

    当我搜索 SanF 时获得 San Francisco 记录 SELECT FROM table WHERE col LIKE san Works SELECT FROM table WHERE col LIKE san F Works S
  • 在浏览器上录制视频并上传到LAMP服务器

    我已经尝试了很多东西 red5 jquery 网络摄像头 html5 但这些解决方案都没有录制视频并准备好上传到服务器 无论如何 html5 flash 等等 更好的跨浏览器解决方案 最好的 上传视频 音频 并将结果上传到服务器 我猜是通过
  • 从 CodeIgniter 中的 URL 捕获哈希值 (#)

    我有一个看起来像的网址 mysite com transactions view 123456 效果很好 但是我的客户现在希望在 url 中包含 hashbang mysite com transactions view 123456 现在
  • 从命令行运行 PHP 脚本

    如何使用用于解析 Web 脚本的 PHP 解释器从命令行运行 PHP 脚本 我有一个phpinfo php从网络访问的文件显示German已安装 但是 如果我运行phpinfo php从命令行使用 php phpinfo php and g
  • 如何以 Magento 方式实现库存过滤器?

    在我的 magento 网站上可以看到缺货的产品 我想要在分层导航中添加一个自定义过滤器 其中显示 排除缺货 当客户单击它时 应该隐藏缺货产品 默认情况下 我在 系统 gt 配置 gt 目录 gt 库存 下启用显示 显示缺货产品 即我希望客

随机推荐