今天用pthreads来解决耗时操作阻塞主线程的问题,但是自动加载一直不成功。试了各种解决办法都不可行,直到发现别人提交的BUG,才发现无解,生产环境慎用。

具体业务在这里简化为三个文件,分别为run.php、Demo.php、Task.php,其中,run.php为入口、Task.php为线程类、Demo.php为模拟的具体逻辑。

文件内容

  • Demo.php

    <?php
    
    namespace core;
    
    class Demo
    {
      public static function method(): string
      {
          return "Demo::method()\r\n";
      }
    }
  • Task.php

    <?php
    
    namespace core;
    
    class Task extends \Thread
    {
      public function run(): void
      {
          file_put_contents('temp.txt', Demo::method(), FILE_APPEND);
      }
    }
  • run.php

    <?php
    
    // composer自动加载
    require 'vendor/autoload.php';
    
    $task = new \core\Task();
    $task->start();
    
    echo "主线程结束\r\n";

    执行/复现

    此处得到结果

    PHP Fatal error:  Uncaught Error: Class 'core\Demo' not found in C:\Users\topnuo
    mi\Desktop\thread\core\Task.php:9
    Stack trace:
    #0 [internal function]: core\Task->run()
    #1 {main}
    thrown in C:\Users\topnuomi\Desktop\thread\core\Task.php on line 9
    主线程结束

    这个结果并不是设想到的结果,自动加载没有在子线程生效。接着再次尝试将spl_autoload_register函数写进Task的run方法中,同样不会生效,令人困惑。

总结

经过测试,主线程中的常量、函数是可以被子线程继承的,但是自动加载没有被继承,具体能继承主线程的什么只能自己去测试了,谷歌、百度都没搜到(方式不对?)。折腾一番后依然没有能解决问题,当看到有其他人已经将这个问题提交到PHP Bugs去的时候,我就基本确定这个问题暂时无解。自动加载目前来看是真的不会继承,只能靠require/include解决子线程中的文件加载问题,在依赖过多的情况下,真的会让人很难受。

已经提交的BUG如下(https://bugs.php.net/bug.php?id=72528

002331.png

另一个问题

在执行上面操作的时候,还遇到一个奇怪的问题
将Task.php改造为如下:

<?php

namespace core;

class Task extends \Thread
{

    public function run(): void
    {
        sleep(2);
    }

}

run.php入口改造为如下,开启两个子线程:

<?php

require 'vendor/autoload.php';

// 线程1
$task1 = new \core\Task();
$task1->start();

// 线程2
$task2 = new \core\Task();
$task2->start();

echo "主线程结束\r\n";

执行script.php,主线程立即执行完成,子线程在2秒后全部执行完成,是我们预想的结果。接下来换一种写法,如下:

<?php

require 'vendor/autoload.php';

// 线程1
(new \core\Task())->start();

// 线程2
(new \core\Task())->start();

echo "主线程结束\r\n";

直接new出来一个Task对象,然后调用其start方法开启线程,本来想的是2秒后执行完成,但是结果却是4秒后全部执行完成,再次令人困惑。

注:本文中的多线程实现为pthreads扩展

标签: pthreads, 多线程

添加新评论