5

在没有函数原型之外的任何文档的情况下,我正在努力寻找 mysqli_poll() 函数的第三个参数是什么。

int mysqli_poll ( 
     array &$read , 
     array &$error , 
     array &$reject , 
     int $sec 
     [, int $usec ] )

查看(C)源代码,它似乎用资源填充 $reject 数组,其中......

CONN_GET_STATE((*p)->data) <= CONN_READY 
   || CONN_GET_STATE((*p)->data) == CONN_QUIT_SENT

这是否意味着与服务器的连接正在关闭/关闭?

还有什么?

是否应该预先填充资源以检查是否断开连接?还是会从 $read 和 $error 自动添加它们?

4

3 回答 3

3

数组绑定到 select() 系统调用。

正如你在这里看到的:http: //lxr.php.net/xref/PHP_5_5/ext/mysqlnd/mysqlnd.c#1384

所以,是的,根据select(2)man 文档:

Select() 检查其地址在 readfds、writefds 和 errorfds 中传递的 I/O 描述符集,以分别查看它们的某些描述符是否已准备好读取、已准备好写入或有异常情况未决。

writefds这里不重要,实现中忽略)

如果另一个用 mysqli 对象填充,则 or 数组允许为空$read$error

$read必须是一个包含要轮询的 mysqli 对象的数组。

$error必须是一个包含要检查异常数据的 mysqli 对象的数组。

正如您从http://lxr.php.net/xref/PHP_5_5/ext/mysqlnd/mysqlnd_enum_n_def.h#322http://lxr.php.net/xref/PHP_5_5/ext/mysqlnd/mysqlnd.c#看到的1228,不匹配的所有内容都<= CONN_READY || == CONN_QUIT_SENT意味着CONN_QUERY_SENT, CONN_SENDING_LOAD_DATA, CONN_FETCHING_DATA, CONN_NEXT_RESULT_PENDING(即尚未准备好获取数据;名称应该不言自明)将不会添加到就绪数组中 == 将是$rejected

$rejected当你将它传递给函数时,它可以是任何东西;它将被一个数组覆盖,其中的条目$read尚未准备好被读取。

于 2013-07-27T00:16:22.077 回答
1

我相信这就是被拒绝的线程结束的地方。

看这个例子: https ://svn.osgeo.org/mapguide/sandbox/rfc94/Oem/php/ext/mysqli/tests/mysqli_poll.phpt

于 2013-07-26T23:42:54.857 回答
0

我建立了一个测试台:

$l1 = mysqli_connect();
$l2 = mysqli_connect();
$l3 = mysqli_connect();

$s1 = "SELECT CURTIME()";
$s2 = "SELECT * FROM";   // will error #1064
$s3 = "SELECT SLEEP(10), CURTIME()";

mysqli_query($l1, $s1, MYSQLI_ASYNC);
mysqli_query($l2, $s2, MYSQLI_ASYNC);
mysqli_query($l3, $s3, MYSQLI_ASYNC);

$started=time();

for ($x=0; $x<5; $x++) {
        $ready=$reject=$errors = array($l1, $l2, $l3);
        print "\niteration $x at t+" . (time()-$started) . "\n";
        mysqli_poll($ready, $errors, $reject, 3);
        print "ready = " . count($ready) . "\n";
        foreach($ready as $r) {
           $c=mysqli_reap_async_query($r);
           print "err=" . mysqli_error($r) . " cnt=" . count($c) . "\n";
        };
        print "errors = " . count($errors) . "\n";
        print "reject = " . count($reject) . "\n";
        sleep(4);
 }

结果(以 // 为前缀的注释):

iteration 0 at t+0
ready = 1              // appears to be SELECT CURTIME()
err= cnt=1
errors = 0
reject = 0

iteration 1 at t+4
ready = 1              // appears to be SELECT * FROM
err=You have an error in your SQL syntax; check the manual that corresponds 
  to your MySQL server version for the right syntax to use near '' at line 
  1 cnt=1
errors = 0
reject = 1             // appears to be SELECT CURTIME() (results reaped)

iteration 2 at t+8
ready = 1              // appears to be SELECT SLEEP(10) despite 8 seconds elapsed
err= cnt=1
errors = 0
reject = 2             // appears to be SELECT CURTIME() + SELECT * FROM

iteration 3 at t+14
ready = 0
errors = 0
reject = 3

iteration 4 at t+21
ready = 0
errors = 0
reject = 3

即 $reject 正在填充已获得结果的链接,而不是尚未准备好轮询的链接。

尝试使用无效连接,从所有数组中删除该值(未添加到 $reject),

于 2013-07-28T15:15:59.903 回答