php三种实现多线程类似的方法
1、curl_multi方法
当需要多线程的时候,可以用curl_multi一次性请求多个操作来完成,但curl走的是网络通信,效率与可靠性就比较差了的。
functionmain(){
$sql="selectwaybill_id,order_idfromwaybillwherestatus>40orderbyupdate_timedesclimit10";
$data=Yii::app()->db->createCommand($sql)->queryAll();//yii框架格式
foreach($dataas$k=>$v){
if($k%2==0){//偶数发一个网址
$send_data[$k]['url']='';
$send_data[$k]['body']=$v['waybill_id'];
}else{//奇数发送另外一个网址
$send_data[$k]['url']='http://www.abc.com';
$send_data[$k]['body']=array($v['order_id']=>array('extra'=>16));
}
}
$back_data=sendMulitRequest($send_data);
var_dump($back_data);
}
functionsendMulitRequest($send_data){
$params=array();
$curl=$text=array();
$handle=curl_multi_init();
foreach($dataas$k=>$v){
if(empty($v['url'])){
$v['url']="http://www.xxx.com";//ifurlisempty,setdefaluturl
}
$reqBody=json_encode($v['body']);
$reqStream=array(
'body'=>$reqBody,
);
$encRequest=base64_encode(json_encode($reqStream));
$params['data']=$encRequest;
$curl[$k]=curl_init();
curl_setopt($curl[$k],CURLOPT_URL,$v['url']);
curl_setopt($curl[$k],CURLOPT_POST,TRUE);
curl_setopt($curl[$k],CURLOPT_HEADER,0);
curl_setopt($curl[$k],CURLOPT_POSTFIELDS,http_build_query($params));
curl_setopt($curl[$k],CURLOPT_RETURNTRANSFER,1);
curl_multi_add_handle($handle,$curl[$k]);
}
$active=null;
do{
$mrc=curl_multi_exec($handle,$active);
}while($mrc==CURLM_CALL_MULTI_PERFORM);
while($active&&$mrc==CURLM_OK){
if(curl_multi_select($handle)!=-1){
do{
$mrc=curl_multi_exec($handle,$active);
}while($mrc==CURLM_CALL_MULTI_PERFORM);
}
}
foreach($curlas$k=>$v){
if(curl_error($curl[$k])==""){
$text[$k]=(string)curl_multi_getcontent($curl[$k]);
}
curl_multi_remove_handle($handle,$curl[$k]);
curl_close($curl[$k]);
}
curl_multi_close($handle);
return$text;
}
2、通过stream_socket_client方式
functionsendStream(){
$english_format_number=number_format($number,4,'.','');
echo$english_format_number;
exit();
$timeout=10;
$result=array();
$sockets=array();
$convenient_read_block=8192;
$host="test.local.com";
$sql="selectwaybill_id,order_idfromxm_waybillwherestatus>40orderbyupdate_timedesclimit1";
$data=Yii::app()->db->createCommand($sql)->queryAll();
$id=0;
foreach($dataas$k=>$v){
if($k%2==0){
$send_data[$k]['body']=NoticeOrder::getSendData($v['waybill_id']);
}else{
$send_data[$k]['body']=array($v['order_id']=>array('extra'=>16));
}
$data=json_encode($send_data[$k]['body']);
$s=stream_socket_client($host.":80",$errno,$errstr,$timeout,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
if($s){
$sockets[$id++]=$s;
$http_message="GET/php/test.php?data=".$data."HTTP/1.0\r\nHost:".$host."\r\n\r\n";
fwrite($s,$http_message);
}else{
echo"Stream".$id."failedtoopencorrectly.";
}
}
while(count($sockets)){
$read=$sockets;
stream_select($read,$w=null,$e=null,$timeout);
if(count($read)){
/*stream_selectgenerallyshuffles$read,soweneedto
computefromwhichsocket(s)we'rereading.*/
foreach($readas$r){
$id=array_search($r,$sockets);
$data=fread($r,$convenient_read_block);
if(strlen($data)==0){
echo"Stream".$id."closesat".date('h:i:s').".<br>";
fclose($r);
unset($sockets[$id]);
}else{
$result[$id]=$data;
}
}
}else{
/*Atime-outmeansthat*all*streamshavefailed
toreceivearesponse.*/
echo"Time-out!\n";
break;
}
}
print_r($result);
}
3、通过多进程代替多线程
functiondaemon($func_name,$args,$number){
while(true){
$pid=pcntl_fork();
if($pid==-1){
echo"forkprocessfail";
exit();
}elseif($pid){//创建的子进程
static$num=0;
$num++;
if($num>=$number){
//当进程数量达到一定数量时候,就对子进程进行回收。
pcntl_wait($status);
$num--;
}
}else{//为0则代表是子进程创建的,则直接进入工作状态
if(function_exists($func_name)){
while(true){
$ppid=posix_getpid();
var_dump($ppid);
call_user_func_array($func_name,$args);
sleep(2);
}
}else{
echo"functionisnotexists";
}
exit();
}
}
}
functionworker($args){
//dosomething
}
daemon('worker',array(1),2);
以上就是为大家分享的三种php实现多线程类似的方法,希望对大家的学习有所帮助。