客户端使用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函数似乎不可重入。
任何人都可以指出一些规则来确认这是定义的行为,还是这是一个可验证的bug? PHP上的Windows被认为是不是线程安全的吗? 是否需要设置一些标志或应用某些补丁以确保线程安全稳定性? 我们需要使用信号量还是阻塞锁? Fast-CGI或IIS7是否存在某些问题或已知配置?
我没有方便的PHP版本,需要获得有关确切环境的详细信息。请原谅一些遗漏的细节,但如果您知道某些重要信息,请询问。 (嗯,请不要问答案是否没有改变你的回答。)我也是一个.NET人而不是PHP人,所以我可能会错过其他关键的东西或对PHP大师来说很明显
是的,我几个月来一直在寻找其中一些问题的答案,但是对谷歌没有运气或者在SO这里没有运气。我们在这里。
谢谢!