首页 > 开发 > PHP > 正文

php三种实现多线程类似的方法

2024-05-04 23:39:59
字体:
来源:转载
供稿:网友

这篇文章主要介绍了php三种实现多线程类似的方法,需要的朋友可以参考下

1、curl_multi方法

当需要多线程的时候,可以用curl_multi一次性请求多个操作来完成,但curl走的是网络通信,效率与可靠性就比较差了的。

 

 
  1. function main(){  
  2.  
  3. $sql = "select waybill_id,order_id from waybill where status>40 order by update_time desc limit 10 ";  
  4.  
  5. $data = Yii::app()->db->createCommand($sql)->queryAll(); //yii 框架格式  
  6.  
  7. foreach ($data as $k => $v) {  
  8.  
  9. if ($k % 2 == 0) { //偶数发一个网址  
  10.  
  11. $send_data[$k]['url'] = '';  
  12.  
  13. $send_data[$k]['body'] = $v['waybill_id'];  
  14.  
  15. else { //奇数发送另外一个网址  
  16. $send_data[$k]['url'] = 'http://www.abc.com';  
  17.  
  18. $send_data[$k]['body']=array($v['order_id'] => array('extra' => 16));  
  19.  
  20. }  
  21.  
  22. }  
  23.  
  24. $back_data =sendMulitRequest($send_data);  
  25.  
  26. var_dump($back_data);  
  27.  
  28. }  
  29. function sendMulitRequest($send_data){  
  30. $params = array();  
  31. $curl = $text = array();  
  32. $handle = curl_multi_init();  
  33.  
  34. foreach ($data as $k => $v) {  
  35.  
  36. if (empty($v['url'])) {  
  37.  
  38. $v['url'] = "http://www.xxx.com"; //if url is empty,set defalut url  
  39.  
  40. }  
  41.  
  42. $reqBody = json_encode($v['body']);  
  43.  
  44. $reqStream = array(  
  45.  
  46. 'body' => $reqBody,  
  47. );  
  48. $encRequest = base64_encode(json_encode($reqStream));  
  49. $params['data'] = $encRequest;  
  50. $curl[$k] = curl_init();  
  51. curl_setopt($curl[$k], CURLOPT_URL, $v['url']);  
  52. curl_setopt($curl[$k], CURLOPT_POST, TRUE);  
  53. curl_setopt($curl[$k], CURLOPT_HEADER, 0);  
  54. curl_setopt($curl[$k], CURLOPT_POSTFIELDS, http_build_query($params));  
  55. curl_setopt($curl[$k], CURLOPT_RETURNTRANSFER, 1);  
  56. curl_multi_add_handle($handle, $curl[$k]);  
  57. }  
  58. $active = null;  
  59.  
  60. do {  
  61.  
  62. $mrc = curl_multi_exec($handle, $active);  
  63.  
  64. while ($mrc == CURLM_CALL_MULTI_PERFORM);  
  65. while ($active && $mrc == CURLM_OK) {  
  66.  
  67. if (curl_multi_select($handle) != -1) {  
  68.  
  69. do {  
  70.  
  71. $mrc = curl_multi_exec($handle, $active);  
  72.  
  73. while ($mrc == CURLM_CALL_MULTI_PERFORM);  
  74.  
  75. }  
  76.  
  77. }  
  78. foreach ($curl as $k => $v) {  
  79. if (curl_error($curl[$k]) == "") {  
  80. $text[$k] = (string) curl_multi_getcontent($curl[$k]);  
  81. }  
  82. curl_multi_remove_handle($handle, $curl[$k]);  
  83. curl_close($curl[$k]);  
  84. }  
  85. curl_multi_close($handle);  
  86. return $text;  

2、通过stream_socket_client 方式

 

 
  1. function sendStream() {  
  2. $english_format_number = number_format($number, 4, '.''');  
  3.  
  4. echo $english_format_number;  
  5. exit();  
  6. $timeout = 10;  
  7. $result = array();  
  8. $sockets = array();  
  9. $convenient_read_block = 8192;  
  10. $host = "test.local.com";  
  11. $sql = "select waybill_id,order_id from xm_waybill where status>40 order by update_time desc limit 1 ";  
  12. $data = Yii::app()->db->createCommand($sql)->queryAll();  
  13. $id = 0;  
  14.  
  15. foreach ($data as $k => $v) {  
  16. if ($k % 2 == 0) {  
  17. $send_data[$k]['body'] = NoticeOrder::getSendData($v['waybill_id']);  
  18.  
  19. else {  
  20. $send_data[$k]['body'] = array($v['order_id'] => array('extra' => 16));  
  21. }  
  22. $data = json_encode($send_data[$k]['body']);  
  23. $s = stream_socket_client($host . ":80", $errno, $errstr, $timeout, STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT);  
  24. if ($s) {  
  25. $sockets[$id++] = $s;  
  26. $http_message = "GET /php/test.php?data=" . $data . " HTTP/1.0/r/nHost:" . $host . "/r/n/r/n";  
  27. fwrite($s, $http_message);  
  28. else {  
  29. echo "Stream " . $id . " failed to open correctly.";  
  30. }  
  31. }  
  32.  
  33. while (count($sockets)) {  
  34.  
  35. $read = $sockets;  
  36.  
  37. stream_select($read, $w = null, $e = null, $timeout);  
  38. if (count($read)) {  
  39. /* stream_select generally shuffles $read, so we need to  
  40. compute from which socket(s) we're reading. */ 
  41. foreach ($read as $r) {  
  42.  
  43. $id = array_search($r, $sockets);  
  44. $data = fread($r, $convenient_read_block);  
  45. if (strlen($data) == 0) {  
  46. echo "Stream " . $id . " closes at " . date('h:i:s') . ".<br> ";  
  47. fclose($r);  
  48. unset($sockets[$id]);  
  49. else {  
  50. $result[$id] = $data;  
  51. }  
  52. }  
  53. else {  
  54. /* A time-out means that *all* streams have failed  
  55. to receive a response. */ 
  56. echo "Time-out!/n";  
  57. break;  
  58. }  
  59. }  
  60. print_r($result);  
  61.  

3、通过多进程代替多线程

 

 
  1. function daemon($func_name,$args,$number){  
  2. while(true){  
  3. $pid=pcntl_fork();  
  4. if($pid==-1){  
  5. echo "fork process fail";  
  6. exit();  
  7. }elseif($pid){//创建的子进程  
  8.  
  9. static $num=0;  
  10. $num++;  
  11. if($num>=$number){  
  12. //当进程数量达到一定数量时候,就对子进程进行回收。  
  13. pcntl_wait($status);  
  14.  
  15. $num--;  
  16. }  
  17. }else//为0 则代表是子进程创建的,则直接进入工作状态  
  18.  
  19. if(function_exists($func_name)){  
  20. while (true) {  
  21. $ppid=posix_getpid();  
  22. var_dump($ppid);  
  23. call_user_func_array($func_name,$args);  
  24. sleep(2);  
  25. }  
  26. }else{  
  27. echo "function is not exists";  
  28. }  
  29. exit();  
  30. }  
  31. }  
  32. }  
  33. function worker($args){  
  34. //do something  
  35.  
  36. }  
  37. daemon('worker',array(1),2);  

以上就是为大家分享的三种php实现多线程类似的方法,希望对大家的学习有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表