进程,线程,协程
首先得说一下基础,就是进程,线程与协程,大小的关系是进程>线程>协程,而我们所说的swoole让php实现了多线程,其实在这里来说,就是好比让php创建了多个进程,每个进程执行一条线程,从而实现了php"多线程"(java是在一个进程内创建多个线程).
子进程的创建
<?php
//创建一个进程
$process = new swoole_process('callback_function', false);
//进程的回调
function callback_function(swoole_process $worker)
{
//执行一个外部程序
$worker->exec('/www/server/php/70/bin/php', array(__DIR__.'/time.php'));
}
//进程开始
$pid = $process->start();
echo $pid.PHP_EOL;
// 回收结束运行的子进程。
swoole_process::wait();
?>
swoole_process::__construct(callable $function, $redirect_stdin_stdout = false, $pipe_type = 2);
$function
,子进程创建成功后要执行的函数,底层会自动将函数保存到对象的callback
属性上。如果希望更改执行的函数,可赋值新的函数到对象的callback
属性$redirect_stdin_stdout
,重定向子进程的标准输入和输出。启用此选项后,在子进程内输出内容将不是打印屏幕,而是写入到主进程管道。读取键盘输入将变为从管道中读取数据。默认为阻塞读取。$pipe_type
,管道类型,启用$redirect_stdin_stdout
后,此选项将忽略用户参数,强制为1
。如果子进程内没有进程间通信,可以设置为0
多进程的使用
<?php
//写入6个进程
$num=6;
$workers = [];
$urls = [
'http://baidu.com',
'http://sina.com.cn',
'http://qq.com',
'http://baidu.com?search=singwa',
'http://baidu.com?search=singwa2',
'http://baidu.com?search=imooc',
];
//创建多个子进程分别模拟请求URL的内容
for($i = 0; $i < $num; $i++) {
$process = new swoole_process(function(swoole_process $worker) use($i, $urls) {
// curl
$content = curlData($urls[$i]);
//将内容写入管道
//echo $content.PHP_EOL;
$worker->write($content.PHP_EOL);
}, true);
$pid = $process->start();
$workers[$pid] = $process;
}
// 获取管道内容
foreach($workers as $v) {
echo $v->read();
}
/**
* 模拟请求URL的内容 1s
* @param $url
* @return string
*/
function curlData($url) {
sleep(1);
return $url . "success".PHP_EOL;
}
运行结果:
原本是6个url的访问任务,通过多进程的创建和使用,最后只需要1s多的时间便完成了运行,swoole多进程的开发和golang的go和类似,如果要开启多个进程,必须要使用多进程中间的channle,也就是说swoole里面的$worker->write($content.PHP_EOL)和$v->read()必不可少,否则会像是golang一样发生阻塞.(除非设置setBlocking为非阻塞)