PHP中使用协同程序实现合作多任务第1/2页(6)_PHP教程
教程Tag:暂无Tag,欢迎添加,赚取U币!
推荐:PHP中使用协同程序实现合作多任务PHP5.5一个比较好的新功能是实现对生成器和协同程序的支持。对于生成器,PHP的文档和各种其他的博客文章(就像这一个或这一个)已经有了非常详细的讲解。协同程序相对受到的关注就少了,所以协同程序虽然有很强大的功能但也很难被知晓,解释起来也比较困难。 这篇文章
需要在某个地方注册这个任务,例如,你可以在run()方法的开始增 加$this->newTask($this->ioPollTask())。然后就像其他 任务一样每执行完整任务循环一次就执行轮询操作一次(这么做一定不是最好的方法)。ioPollTask将使用0秒的超时来调用ioPoll, 这意味着stream_select将立即返回(而不是等待)。
只有任务队列为空时,我们才使用null超时,这意味着它一直等到某个套接口准备就绪。如果我们没有这么做,那么轮询任务将一而再, 再而三的循环运行,直到有新的连接建立。这将导致100%的CPU利用率。相反,让操作系统做这种等待会更有效。
现在编写服务器相对容易了:
<?php
function server($port) {
echo "Starting server at port $port...\n";
$socket = @stream_socket_server("tcp://localhost:$port", $errNo, $errStr);
if (!$socket) throw new Exception($errStr, $errNo);
stream_set_blocking($socket, 0);
while (true) {
yield waitForRead($socket);
$clientSocket = stream_socket_accept($socket, 0);
yield newTask(handleClient($clientSocket));
}
}
function handleClient($socket) {
yield waitForRead($socket);
$data = fread($socket, 8192);
$msg = "Received following request:\n\n$data";
$msgLength = strlen($msg);
$response = <<<RES
HTTP/1.1 200 OK\r
Content-Type: text/plain\r
Content-Length: $msgLength\r
Connection: close\r
\r
$msg
RES;
yield waitForWrite($socket);
fwrite($socket, $response);
fclose($socket);
}
$scheduler = new Scheduler;
$scheduler->newTask(server(8000));
$scheduler->run();
这段代码将接收到localhost:8000上的连接,然后仅仅返回发送来的内容作为HTTP响应。要做“实际”的事情的话就爱哪个非常复杂(处理 HTTP请求可能已经超出了这篇文章的范围)。上面的代码片段只是演示了一般性的概念。
你 可以使用类似于ab -n 10000 -c 100 localhost:8000/这样命令来测试服务器。这条命令将向服务器发送10000个请求,并且其中100个请求将同时到达。使用这样的数目,我得 到了处于中间的10毫秒的响应时间。不过还有一个问题:有少数几个请求真正处理的很慢(如5秒), 这就是为什么总吞吐量只有2000请求/秒(如果是10毫秒的响应时间的话,总的吞吐量应该更像是10000请求/秒)。调高并发数(比如 -c 500),服务器大多数运行良好,不过某些连接将抛出“连接被对方重置”的错误。由于我对低级别的socket资料了解的非常少,所以 我不能指出问题出在哪儿。
协程堆栈
如果你试图用我们的调度系统建立更大的系统的话,你将很快遇到问题:我们习惯了把代码分解为更小的函数,然后调用它们。然而, 如果使用了协程的话,就不能这么做了。例如,看下面代码: 复制代码 代码如下:
<?php
function echoTimes($msg, $max) {
for ($i = 1; $i <= $max; ++$i) {
echo "$msg iteration $i\n";
yield;
}
}
function task() {
echoTimes('foo', 10); // print foo ten times
echo "---\n";
echoTimes('bar', 5); // print bar five times
yield; // force it to be a coroutine
}
$scheduler = new Scheduler;
$scheduler->newTask(task());
$scheduler->run();
分享:php修改NetBeans默认字体的大小在Netbeans中由于使用了Swing进行开发,所以其中界面的字体也是由Java虚拟机进行配置而不是随操作系统的。在安装完Netbeans后默认的字体大小是11px。而在Windows下的宋体最小支持12px。所以字体为11px就已经无法完整显示了。 简单的解决办法就是将字体改大一点。详细的
相关PHP教程:
- 相关链接:
- 教程说明:
PHP教程-PHP中使用协同程序实现合作多任务第1/2页(6)。