代码之家  ›  专栏  ›  技术社区  ›  ashurexm

php中的多线程/并行处理

  •  2
  • ashurexm  · 技术社区  · 15 年前

    我有一个php脚本,它将使用phpexcel从mysql数据库查询的数据生成一个报告。目前,它的处理是线性的,它从mysql获取数据,读取excel模板,将数据写入模板,然后输出。我对代码进行了优化,使数据只重复一次,而在php端几乎没有处理。查询在不到.001秒的时间内返回数百行,因此运行速度足够快。经过一段时间后,我发现我的瓶颈是(惊喜,惊喜)阅读模板和编写输出。 我想这样做:

    Spawn a thread/process to read the template
    Spawn a thread/process to fetch the data
    Return back to parent thread - Parent thread will wait until both are complete
    Proceed on as normal
    

    我的主要问题是这可能吗,值得吗?如果双方都同意,你会怎么处理? 而且,它是CentOS上的PHP5

    6 回复  |  直到 13 年前
        1
  •  8
  •   Kevin Schroeder    15 年前

    通常,分叉apache进程不是一个好主意。这可能会导致不确定的结果。相反,最好使用某种排队机制。gearman是一种可以使用的开源排队机制。我还有一篇关于zend服务器作业队列的博客文章,其中讨论了异步运行任务的问题。 Do you queue? Introduction to the Zend Server Job Queue .

    您还可以使用类似zend框架队列类的东西来实现一些异步工作。 Zend_Queue

    @swisstack,我也不同意您关于php不是为高性能而创建的断言。语言特征很少是导致表演缓慢的原因。也许通过对不同语言之间的$a++进行原始语言测试,您会看到这一点,但是这种测试是不相关的。我在php上做了几年的咨询,从来没有看到过由于这种语言导致的性能问题。

        2
  •  1
  •   Scott Saunders    15 年前

    我会尝试找出你是否可以缓存或存储模板在一些更快的阅读格式。我不知道这是否可能,但phpexcel论坛相当不错,开发人员也在关注。

        3
  •  1
  •   webbiedave    15 年前

    你不能多线程,但你可以分叉( pcntl_fork , pcntl_wait )正如我所知道的,您将需要仔细测试进程生成时间,以确保这甚至是值得为您的情况。

    $pid = pcntl_fork();
    
    if ($pid == -1) {
      // fork failed
    
    } elseif ($pid > 0) {
      // we're the parent! Wait for child to finish
      pcntl_waitpid($pid);
    
    } else {
      // we're the child
    }
    
        4
  •  1
  •   goat    15 年前

    如果读取模板和数据库查询都很慢,那么我认为通过并行运行任务可以获得有价值的性能。但是,您自己说过,读取模板很慢,数据库查询也很快。因此,即使忽略了并行运行任务所需的额外开销,在最佳情况下,也可以节省0.001秒(db query所需的时间)。

    并行运行多个任务仍然需要最慢任务的时间。按系列运行任务是所有任务的总和。在你的例子中,templateTime+queryTime(0.001)

    我觉得不值得。

    通常数据库是方程式中的乌龟。你可以不用太多的努力就完成那部分异步。查看新添加的mysqli_poll()和friend函数。

        5
  •  0
  •   maraspin    15 年前

    你完全可以用php在centos上生成进程( http://php.net/manual/en/function.pcntl-fork.php )不过,在那之前,我至少要考虑一件事…如果瓶颈出现在读取模板和写入输出上,则可能只是一个I/O绑定问题,因此处理多个进程可能没有多大帮助…就我个人而言,我想看看是否可以做一些缓存,而不是…

        6
  •  0
  •   Mark Baker    15 年前

    读取模板一次,然后对需要从数据创建的每个工作簿执行克隆

    推荐文章