【问题标题】:how to use multithreading in php如何在php中使用多线程
【发布时间】:2012-05-16 00:38:48
【问题描述】:

我现在正在开发一个关于在 Internet 上共享视频的网站。 流程如下: 用户上传视频->服务器端接收视频并使用ffmpeg将视频格式转换为flv->用户继续在站点中做其他事情。 现在我想建立另一个线程来做转换工作(使用ffmpeg将视频格式转换为flv),这样用户就可以在不等待视频转换为flv的情况下做其他事情。但不知道怎么做!

【问题讨论】:

  • 您是否打算在视频转换完成时通知用户?
  • PHP 不是,从来没有,也可能永远不会是多线程的。最好的办法是 exec() 一个外部脚本来完成这项工作。

标签: php multithreading ffmpeg


【解决方案1】:

PHP 不支持线程。您应该使用由 cron 脚本运行的后台任务来执行此操作。

您可以有一个表,其中包含要处理的作业,例如,包含磁盘上的文件名、状态(待处理、转换、准备好)等,然后让脚本处理所有待处理作业,更改它们的状态转换,转换文件,然后将状态更改为就绪。通过这种方式,您还可以将信息呈现给用户,如果您希望同时转换多个文件,则可以运行多个脚本。

【讨论】:

  • @DenisErmolin,当然,但这不是线程。另外,分叉 request 来运行 ffmpeg 可能是一个非常糟糕的主意。
  • @DenisErmolin pcntl_fork() 在 Web 请求的上下文中实际上不起作用,如果您退出主进程以返回响应,您将离开一个孤立的进程。如果你想做这样的事情,exec('php /path/to/script.php > /dev/null 2>&1 &') 会好得多。
【解决方案2】:

制作一个需要转换的视频队列,并以cron 作业为例,逐个转换视频。该队列可以存储在消息队列或数据库之类的东西中。

使用数据库,您可以创建一个包含列IDStartDatetimeEndDatetimeFilenameStatusOwner 的表,并在上传视频时适当设置这些列。当一些用户请求他或她的任何视频的状态时,您只需在数据库中查找状态,其中(例如)1 = 已添加,2 = 当前正在处理,3 = 完成,4 = 错误。

现在您的 cron 作业开始处理所有项目,其中状态等于 1;处理时将其更新为 2,然后适当地更新为 3 或 4。


通过所有类似 fork/exec/run-on-background 的解决方案,您可以立即开始处理上传的视频,您允许所有用户阻塞服务器。如果多个用户同时开始处理一个大视频怎么办?您无法控制单独的进程,并且所有进程都同时运行,这可能会严重降低您的服务器速度。

通过使用一个进程(从cron 开始)按顺序处理项目,您可以更好地管理正在使用的资源。

【讨论】:

    【解决方案3】:

    看起来像是job server 的工作。只需将其添加为background task

    【讨论】:

      【解决方案4】:

      PHP 在任何方式、形状或形式上都不是多线程的。你可以用一些方法来伪造它,但它们不是真正的“线程”:

      1. ignore_user_abort(TRUE) 允许脚本在用户断开连接后继续运行。
      2. exec() 可以在 shell 级别启动一个可以在后台运行的新进程,但这将是一个完全独立的进程,如果没有额外的措施,则无法从父脚本控制
      3. pcntl_fork() 将创建当前脚本的克隆,然后可以继续处理,但名义上将再次独立于父脚本。这需要pcntl 扩展可用,并且在网络请求的上下文中使用是不安全的。

      【讨论】:

        【解决方案5】:

        您可以将 ffmpeg 作为后台进程生成。 详解见here

        我建议将上传的视频文件保存在某处,然后在其上运行 ffmpeg,并显示“正在处理文件..”直到文件创建(但您不必等待 ffmpeg,只需检查它是否已创建文件)。

        另一种选择是将文件放在某个目录中,例如 /videos。然后创建一个 cron 作业,它将监控 /videos 文件夹并转换任何新文件。

        当然,你可以想出一个更精细、更安全的方法。

        【讨论】:

          【解决方案6】:

          我认为人们通常会求助于 Gearman 来完成这些任务:http://php.net/manual/en/book.gearman.php

          【讨论】:

            猜你喜欢
            • 2010-09-09
            • 1970-01-01
            • 2016-12-01
            • 2020-12-28
            • 2021-08-04
            • 2018-10-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多