哪里非阻塞了,为什么非阻塞?
主进程非阻塞了,因为本代码在运行的过程中不需要等待。所以本代码主进程非阻塞,再说一遍,是主进程非阻塞。
哪里异步了,为什么异步?
本代码利用了多进程fork产生了很多子进程,本人认为异步应该有参考,才能看出本进程是否同步还是异步。由于产生了很多子进程,子进程工作有快有慢,估任一子进程相对于其他子进程是异步的。相对于主进程也是异步的。故子进程异步了,因为工作有快有慢。
异步为什么要回调或者使用信号、或者使用状态来通知?
本代码中利用了fork产生多个进程,由于进程之间的上下文(上下代码的变量值)各不相同。所以进程之间不得传递数据。只能利用奇巧淫技来处理子进程的结果。常用的可以使用callback函数、LINUX系统的进程之间传递信号、状态。
1、传递callback:
传递给子进程,子进程得到结果后给callback函数处理,其实还是使用了cpu给子进程分配的运行时间片。
2、LINUX信号:
简单说就是子进程通过信号,通知主进程,说我完成了。那么数据怎么传?可以通过有名管道(比如用子进程的pid命名)、内存共享等等。得到子进程的结果。
3、状态:
可以利用redis的sub\pub来模拟linux信号进行通知,用redis的特性来传递数据。跟linux的信号无异。
<?php
pcntl_signal(SIGCHLD, SIG_IGN);
function asynchronousTask(callable $functionName, $params) {
$apid = pcntl_fork();
if ($apid == -1) {
exit('could not fork for client ' . $client);
} else if ($apid) {
return;
} else {
call_user_func_array($functionName, $params);
exit();
}
}
function httpCurl($url, $data, $requestType = 'get', $callback = '') {
//初始化curl
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if (strtolower($requestType) == 'post') {
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
}
$return = curl_exec($ch);
curl_close($ch);
if (is_callable($callback)) {
$callback($return);
}
return;
}
for($i = 0; $i <= 10; $i++) {
asynchronousTask('httpCurl', ['http://www.baidu.com', '', 'get', function ($data) {
sleep(rand(1, 3)); // 用于卡住本子进程,模拟子进程不同的工作效率。
echo strlen($data) . "\n";
}]);
}