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";