客户端使用 PHP 如下:
function getBlah($something) {
$p1 = "foo";
$p2 = "bar";
$obj = new COM("namespace.class");
$result = $obj->method($p1,$p2,$something);
unset($obj);
$blah = explode(chr(10),$result); // and do other stuff
echo $blah;
}
COM 对象是一个 VB.NET 类。此代码有效。PHP 正在从网页执行。
在 .NET 方法中,另一个类被实例化,它与服务器进行通信。该方法完成后,我们“假设”.NET 垃圾收集将处理所有资源。我们进一步“假设”在 PHP 方法完成后,COM 对象将通过 PHP GC 打包,并且这些资源将不可用于其他进程。
但是我们发现,当多个用户同时点击该函数时,在 .NET 方法对象中实例化的线程正在被重用。因此 user1 执行 PHP,实例化 COM 对象并调用方法,创建托管对象,该对象在线程中创建并等待服务器响应几毫秒到几秒。现在 user2 做了同样的事情,但不知何故 user1 的响应回到了 user2 的线程上。因此,一个或两个进程都会返回,其中一个可能会收到另一个线程的响应!
是的,我们都知道“假设”是什么意思,并且我们已经尝试了各种可能的显式资源处理。
这里的另一个问题表达了完全相反的问题:Is it possible to cache/serialize a COM object in PHP? 对此的回应说不,但这可能证明并非如此。
重现这一点可能非常困难,但它偶尔发生的事实非常令人恼火——想象一下提交一个网络表单并获得其他人的交易确认——这不好啊?
虽然 PHP 变量的范围对于每个进程都是唯一的,并且每个进程在每个函数结束时都有自己的资源 GC,但似乎分配给 COM 对象的内存在某种程度上是共享的,而两个用户正在执行相同的代码。换句话说,包含 COM 对象的 PHP 函数似乎不是可重入的。
谁能指出一些规则来确认这是已定义的行为,或者这是一个可验证的错误?
Windows 上的 PHP 是否被认为不是线程安全的?
是否需要设置一些标志或应用一些补丁以确保线程安全的稳定性?
我们需要使用信号量还是阻塞锁?
Fast-CGI 或 IIS7 是否存在一些问题或已知配置?
我没有方便的 PHP 版本,需要获取有关确切环境的详细信息。请原谅一些遗漏的细节,但如果您知道某些重要的事情,请询问。(嗯,请不要问答案是否不会改变你的回答。)我也更像一个 .NET 人而不是 PHP 人,所以我可能在这里遗漏了一些其他重要的东西,或者对 PHP 大师来说很明显.
是的,几个月来我一直在寻找其中一些问题的答案,但在谷歌或在 SO 上都没有运气。所以我们在这里。
谢谢!