【问题标题】:How do PHP's p* connect methods work?PHP 的 p* 连接方法是如何工作的?
【发布时间】:2009-08-26 03:56:25
【问题描述】:

我的理解是 PHP 的 p* 连接是它在页面加载到服务(无论是内存缓存还是套接字等)之间保持连接持久。但是这些连接线程安全吗?当两个页面试图同时访问同一个连接时会发生什么?

【问题讨论】:

  • 我敢打赌有人说你可以自己测试。哦,看..我刚刚做到了。 :P

标签: php networking


【解决方案1】:

在典型的 unix 部署中,PHP 安装为在 apache Web 服务器内运行的一个模块,该服务器又被配置为将 HTTP 请求分派给多个衍生的子节点之一。

为了效率,apache往往会提前派生出这些进程(pre-forking它们)并维护它们,这样它们就可以分派多个请求,节省了为每个请求启动一个进程的开销进来的。

PHP 的工作原理是在干净的环境中启动每个请求;页面加载之间没有脚本变量持续存在。 (与 mod_perl 或 python 相比,应用程序通常会由于意外的状态宿醉而表现出细微的错误)。

这意味着由 PHP 脚本分配的典型资源,无论是用于 GD 的图像句柄还是数据库连接,都将在请求结束时释放。

某些资源,尤其是 Oracle 数据库连接,建立起来的成本相当高,因此希望以某种方式在分派的 Web 请求之间缓存该连接。

输入持久性资源。

这些工作的方式是任何给定的 apache 子进程都可以通过将资源注册到资源的“持久列表”中来维护超出请求范围的资源。在请求结束时不会清理持久列表(内部称为 RSHUTDOWN)。当您使用 pconnect 函数时,它会在持久列表条目中查找一组给定的唯一凭据并返回(如果存在),或者与这些凭据建立新连接。

如果您已将 apache 配置为维护 200 个子进程,您应该会看到从 Web 服务器到数据库计算机建立的许多连接。

如果您有许多 Web 服务器和一台数据库机器,您最终加载的数据库机器可能比您预期的要多。

使用线程 SAPI,持久列表是按线程维护的,因此它应该是线程安全的并且具有类似的好处,但是关于不建议在线程 SAPI 中运行 PHP 的常见警告适用——而 PHP 本身是线程安全的,它使用的这么多库可能有它们自己的线程安全问题,让你很头疼。

【讨论】:

    【解决方案2】:

    手册页Persistent Database Connections 可能会为您提供一些关于持久连接的信息。

    它仍然没有具体说明线程安全;据我所知,我从未在任何地方看到过任何关于此的事情,所以我认为它“工作正常”。我的猜测是只有在没有被另一个线程同时使用的情况下才会重新使用连接,但这只是某种(逻辑)疯狂猜测......

    【讨论】:

      【解决方案3】:

      一般来说,PHP 会在网络服务器上运行的每个进程或线程建立一个持久连接。因此,一个进程或线程不会访问另一个进程或线程的连接。

      相反,当你建立一个数据库连接时,PHP 会检查一个是否已经打开(在处理页面请求的进程或线程中),如果是,那么它将使用它,否则它只会初始化一个新的。

      所以要回答您的问题,它们不一定是线程安全的,但由于它们的操作方式,不会出现两个线程或进程访问同一个连接的情况。

      【讨论】:

        【解决方案4】:

        一般来说,当一个 PHP 脚本请求一个持久连接时,PHP 会在连接池中寻找一个具有相同连接参数的连接。

        如果发现一个未被使用,则将其提供给脚本,并在脚本结束时返回到池中。

        【讨论】:

        • 在 Windows 上运行 PHP 怎么样,你总是使用线程版本?顺便说一句,在 UNIX 上与 Apaches worker MPM 相同。
        猜你喜欢
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 2012-04-15
        • 2023-03-30
        • 2018-04-24
        • 2016-01-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多