Process是swoole内置的进程管理模块,用来替代PHP的pcntl扩展。php
swoole_process支持重定向标准输入和输出,在子进程内echo不会打印屏幕,而是写入管道,读键盘输入能够重定向为管道读取数据。html
配合swoole_event模块,建立的PHP子进程能够异步的事件驱动模式。react
函数原型:git
int swoole_process::__construct(mixed $function, $redirect_stdin_stdout = false, $create_pipe = true);
$function
,子进程建立成功后要执行的函数,底层会自动将函数保存到对象的callback属性上。$redirect_stdin_stdout
,重定向子进程的标准输入和输出。启用此选项后,在进程内echo将不是打印屏幕,而是写入到管道。读取键盘输入将变为从管道中读取数据。默认为阻塞读取。$create_pipe
,是否建立管道,启用$redirect_stdin_stdout
后,此选项将忽略用户参数,强制为true 若是子进程内没有进程间通讯,能够设置为false。SOCK_STREAM
流式$create_pipe
为2时,管道类型将设置为SOCK_DGRAM
。<?php $process = new swoole_process(function(swoole_process $worker){ while (true){ $cmd = $worker->read(); passthru($cmd); } }, true, 2); $process->start(); $process->write('ls -l');//将参数传入子进程内 echo $data = $process->read();//获取执行结果
实例:web版本的shell
https://github.com/52fhy/swoole_demo/blob/master/swoole_shell_server.phpgithub
swoole还提供了直接操做底层epoll/kqueue事件循环的接口。可将其余扩展建立的socket,PHP代码中stream/socket扩展建立的socket等加入到Swoole的EventLoop中。web
swoole_event_add函数用于将一个socket加入到swoole的reactor事件监听中。 函数原型:shell
bool swoole_event_add(int $sock, mixed $read_callback, mixed $write_callback = null, int `$flags` = null);
$sock
支持文件描述符、stream资源、sockets资源。$read_callback
为可读回调函数。$write_callback
为可写事件回调。$flags
为事件类型的掩码,可选择关闭/开启可读可写事件,如SWOOLE_EVENT_READ
,SWOOLE_EVENT_WRITE
,或者SWOOLE_EVENT_READ | SWOOLE_EVENT_WRITE
。在Server程序中使用,能够理解为在worker/taskworker进程中将此socket注册到epoll事件中。swoole
在Client程序中使用,能够理解为在客户端进程中将此socket注册到epoll事件中。异步
示例:socket
<?php $fp = stream_socket_client("tcp://www.52fhy.com:80", $errno, $errstr, 30); fwrite($fp, "GET / HTTP/1.1\r\nHost: www.52fhy.com\r\n\r\n"); swoole_event_add($fp, function($fp) { echo $resp = fread($fp, 1024); //socket处理完成后,从epoll事件中移除socket swoole_event_del($fp); fclose($fp); }); echo "Finish\n"; //swoole_event_add不会阻塞进程,这行代码会顺序执行
对比一下,下面这个会阻塞进程:
<?php $fp = stream_socket_client ( "tcp://www.52fhy.com:80" , $errno , $errstr , 30 ); if (! $fp ) { echo " $errstr ( $errno )<br />\n" ; } else { fwrite ( $fp , "GET / HTTP/1.1\r\nHost: www.52fhy.com\r\n\r\n" ); while (! feof ( $fp )) { echo fgets ( $fp , 1024 ); } fclose ( $fp ); } echo "Finish\n";