什么:我有一个运行的PHP脚本等待套接字连接。当我连接到套接字时,脚本会打印出资源ID。
问题:资源ID不会增加1而是增加306,000。这当然是一个更大的问题和溢出。导致我的代码最终破裂。
研究:我找不到任何支持我(程序员)需要控制它的文档。我确实发现following link有人陈述同样的问题。
思考:我认为系统会对此进行管理。如果我需要管理资源ID号,那么我该怎么做。
代码片段
<?php
chdir( dirname ( __FILE__ ) );
echo "Waiting for port!\n";
$file = 'change.txt';//change query
do{
$sock = @socket_create_listen('12346'); //port im listening too
sleep(1);
}
while(!(@socket_getsockname($sock, $addr, $port)));
echo "Server Listening on $addr:$port\n";
socket_set_nonblock($sock);
echo"Awaiting Connection\n";
while(true)
{
if($newc = @socket_accept($sock))
{
socket_set_nonblock($newc);
echo "Client $newc has connected\n";
}
$current = file_get_contents($file);
}
?>
帮助:这个想法是(如果你不断连接到套接字,资源ID会溢出)。我的代码很难粘贴,但我减少它以显示问题:
A)什么可能导致资源ID异常增量。
B)如果确定异常增量问题的根本原因是不可行的,那么如何管理资源ID可能有所帮助。
调查结果:最后一个命令“file_get_contents ...”如果此行被注释掉,则代码正常工作且资源ID正确递增。如果没有注释掉并且添加了睡眠,则增量值要好得多但不正确(即跳转5或6个值)。我不确定最近会发生什么。
由于
答案 0 :(得分:3)
PHP不会在内部重新使用资源ID,所以最终你会遇到PHP使用它们的问题,导致你得到的警告。请参阅bug report。由于PHP中的一堆东西会注册资源,增加资源ID,因此在长时间运行的脚本中很容易遇到这个错误。
最大ID取决于您的架构。您可以打印常量PHP_INT_MAX
以获取安装的编号,但在32位系统上,它通常为2,147,483,647。它在64位系统上明显更高。我的打印出9,223,372,036,854,775,807。您不太可能在64位系统上耗尽资源ID限制。
此外,您在无限制file_get_contents
循环中致电while (true)
。在while循环的每次迭代之间没有休眠期,因此循环基本上尽可能快地执行。每个file_get_contents
调用都会导致资源ID指针增加2,因为它使用了2个资源。例如:
<?php
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #4
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #5
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #6
file_get_contents('/etc/hosts');
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #9
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #10
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #11