婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > php多進程應用場景實例詳解

php多進程應用場景實例詳解

熱門標簽:長春人工外呼系統服務商 廣州防封卡外呼系統多少錢一個月 怎么向銷售公司推銷外呼系統 廣東地市地圖標注 哪里辦理400電話 高德地圖標注家 江西手機自動外呼防封系統是什么 外呼系統撥打暫時無法接通 仁和怎么申請400開頭的電話

本文實例講述了php多進程應用場景。分享給大家供大家參考,具體如下:

pcntl介紹

擴展介紹

php多進程模塊依賴pcntl擴展,官方手冊介紹:http://php.net/manual/zh/book.pcntl.php

Note:

1. 此擴展在 Windows 平臺上不可用。
2. 進程控制不能被應用在Web服務器環境,當其被用于Web服務環境時可能會帶來意外的結果。因此,不能再PHP Web開發中使用多進程。

安裝擴展

# 通過pecl安裝pcntl擴展
sudo pecl install pcntl
# 增加 extension=pcntl.so
sodo vim /etc/php.ini
# 檢查擴展是否安裝成功
php -m | grep pcntl

處理文件

當一個文件包含許多任務(每個任務一行),并且各任務之間不存在執行的先后順序關系,可以將文件進行分割(分割后的文件數量與進程數一致),然后使用多進程進行處理。

例如,現在有10個郵箱賬號存儲在文件mailist.txt中,每次發送郵件需要耗時2s,則采用單進程依次發送完這些郵件需要耗時20。
如果采用多進程,例如3個進程進行處理,首先需要將文件按行數拆分成3個小文件,其中兩個文件是4條記錄,一個文件是2條記錄。每個進程處理一個小文件,則不同進程發送完郵件的耗時為8、8、6,總耗時取最大值為8s。

拆分文件

原始文件 maillist.txt

000000@163.com
111111@163.com
222222@163.com
333333@163.com
444444@163.com
555555@163.com
666666@163.com
777777@163.com
888888@163.com
999999@163.com

拆分操作

split -a 1 -l 4 maillist.txt task

拆分后的文件

taska

000000@163.com
111111@163.com
222222@163.com
333333@163.com

taskb

444444@163.com
555555@163.com
666666@163.com
777777@163.com

taskc

888888@163.com
999999@163.com

相關腳本

多進程調用腳本 text_task.php

$cmds = [
  ['/Users/zhezhao/www/work/text_mail.php','a'],
  ['/Users/zhezhao/www/work/text_mail.php','b'],
  ['/Users/zhezhao/www/work/text_mail.php','c']
];
foreach ($cmds as $cmd){
  $pid = pcntl_fork();
  if($pid == -1){
    exit('create process failed');
  }
  if($pid > 0){
    pcntl_wait($status,WNOHANG);
  }else{
    pcntl_exec('/usr/bin/php',$cmd);
  }
}

多進程執行腳本 text_mail.php

require 'MailWork.php';
$name = $argv[1];
echo $name." start #".time().PHP_EOL;
$worker = new MailWork($name);
$res = $worker->text_mail($argc,$argv);
if($res === false){
  echo $worker->getLastError();
}else{
  echo $name." ".$res." works done # ".time().PHP_EOL;
}

輸出結果

c start #1504499765
b start #1504499765
a start #1504499765
b#mailto:444444@163.com
c#mailto:888888@163.com
a#mailto:000000@163.com
b#mailto:555555@163.com
a#mailto:111111@163.com
c#mailto:999999@163.com
c 2 works done # 1504499769
a#mailto:222222@163.com
b#mailto:666666@163.com
b#mailto:777777@163.com
a#mailto:333333@163.com
b 4 works done # 1504499773
a 4 works done # 1504499773

在text_task.php中創建了3個進程(a、b、c),其中a和b處理的文件中有4條記錄,c處理的文件中有2條記錄。

通過輸出結果可以得到:

1. a、b、c 三個進程同時開始執行,開始時間戳1504499765
2. c最先完成,完成時間戳1504499769,耗時4s
3. a和c同時完成,完成時間戳1504499773,耗時8s

處理消息隊列

這是另外一種常見的常見,我們將耗時操作放入消息隊列,通過腳本從消息隊列中取出并執行記錄。如果通過單個進程依次讀取并處理消息,容易使隊列中積累大量數據,導致操作的延遲時間較長,這種場景可以通過多個進程來讀取并處理消息。redis中的pop操作具有原子性,不會存在多個讀取到相同的隊列消息的情況。

多進程調用腳本 redis_task.php

$redis = new Redis();
$redis->connect('192.168.1.10');
$task_key = 'task_list';
$task_list = [
  '000000@163.com',
  '111111@163.com',
  '222222@163.com',
  '333333@163.com',
  '444444@163.com',
  '555555@163.com',
  '666666@163.com',
  '777777@163.com',
  '888888@163.com',
  '999999@163.com',
];
foreach ($task_list as $task){
  $redis->lPush($task_key,$task);
}
$cmds = [
  ['/Users/zhezhao/www/work/redis_mail.php','a'],
  ['/Users/zhezhao/www/work/redis_mail.php','b'],
  ['/Users/zhezhao/www/work/redis_mail.php','c']
];
foreach ($cmds as $cmd){
  $pid = pcntl_fork();
  if($pid == -1){
    exit('create process failed');
  }
  if($pid > 0){
    pcntl_wait($status,WNOHANG);
  }else{
    pcntl_exec('/usr/bin/php',$cmd);
  }
}

多進程執行腳本 redis_mail.php

require 'MailWork.php';
$name = $argv[1];
echo $name." start #".time().PHP_EOL;
$worker = new MailWork($name);
$redis = new Redis();
$redis->connect('192.168.1.10');
$task_key = 'task_list';
while($redis->lLen($task_key)>0){
  $mailto = $redis->rPop($task_key);
  $worker->redis_mail($mailto);
}
echo $name." work done # ".time().PHP_EOL;

輸出結果

b start #1504499844
c start #1504499844
a start #1504499844
b#mailto:000000@163.com
a#mailto:111111@163.com
c#mailto:222222@163.com
b#mailto:333333@163.com
a#mailto:444444@163.com
c#mailto:555555@163.com
b#mailto:666666@163.com
a#mailto:777777@163.com
c#mailto:888888@163.com
c work done # 1504499850
a work done # 1504499850
b#mailto:999999@163.com
b work done # 1504499852

通過輸出結果可以得到

1. a、b、c三個進程同時開始執行,時間戳為1504499844
2. a和c同時結束執行,分別處理了3條記錄,時間戳為1504499850,耗時6s
3. b最后結束執行,處理了4條記錄,時間戳為1504499852,耗時8s

master-worker模式

我們模擬Web服務器處理http請求的操作,對于每個請求創建一個進程,用于處理請求內容。

class WebServer
{
  private $list;
  public function __construct()
  {
    $this->list = [];
  }
  public function worker($request){
    $pid = pcntl_fork();
    if($pid == -1){
      return false;
    }
    if($pid > 0){
      return $pid;
    }
    if($pid == 0){
      $time = $request[0];
      $method = $request[1];
      $start = time();
      echo getmypid()."\t start ".$method."\tat".$start.PHP_EOL;
      sleep($time);
      $end = time();
      $cost = $end-$start;
      echo getmypid()."\t stop \t".$method."\tat:".$end."\tcost:".$cost.PHP_EOL;
      exit(0);
    }
  }
  public function master($requests){
    $start = time();
    echo "All request handle stop at ".$start.PHP_EOL;
    foreach ($requests as $request){
      $pid = $this->worker($request);
      if(!$pid){
        echo 'handle fail!'.PHP_EOL;
        return;
      }
      array_push($this->list,$pid);
    }
    while(count($this->list)>0){
      foreach ($this->list as $k=>$pid){
        $res = pcntl_waitpid($pid,$status,WNOHANG);
        if($res == -1 || $res > 0){
          unset($this->list[$k]);
        }
      }
      usleep(100);
    }
    $end = time();
    $cost = $end - $start;
    echo "All request handle stop at ".$end."\t cost:".$cost.PHP_EOL;
  }
}
$requests = [
 [1,'GET index.php'],
 [2,'GET index.php'],
 [3,'GET index.php'],
 [4,'GET index.php'],
 [5,'GET index.php'],
 [6,'GET index.php']
];
$server = new WebServer();
$server->master($requests);

輸出結果:

All request handle stop at 1504513048
18945    start GET index.php    at1504513048
18944    start GET index.php    at1504513048
18946    start GET index.php    at1504513048
18947    start GET index.php    at1504513048
18948    start GET index.php    at1504513048
18949    start GET index.php    at1504513048
18944    stop   GET index.php   at:1504513049   cost:1
18945    stop   GET index.php   at:1504513050   cost:2
18946    stop   GET index.php   at:1504513051   cost:3
18947    stop   GET index.php   at:1504513052   cost:4
18948    stop   GET index.php   at:1504513053   cost:5
18949    stop   GET index.php   at:1504513054   cost:6
All request handle stop at 1504513054    cost:6

如果依次處理請求,總耗時為1+2+3+4+5+6=21s。每個請求創建一個進程的處理方式,總耗時是最耗時的請求操作6s。

多進程最好在方法、函數或者文件中單獨使用,這樣邏輯更加清晰,也便于分析和維護。

附錄

郵件操作類:

MailWork.php

?php
/**
 * Created by PhpStorm.
 * User: zhezhao
 * Date: 2017/9/4
 * Time: 上午10:05
 */
class MailWork
{
  private $error;
  private $name;
  public function __construct($name)
  {
    $this->name = $name;
  }
  public function getLastError(){
    return $this->error;
  }
  public function checkEnv($argc)
  {
    if (substr(php_sapi_name(), 0, 3) !== 'cli') {
      $this->error ="This Programe can only be run in CLI mode";
      return false;
    }
    if($argc!=2){
      $this->error = 'wrong params';
      return false;
    }
    return true;
  }
  public function getFileName($argv){
    $filename = "task".$argv[1];
    if(!file_exists($filename)){
      $this->error = 'file does not exits';
      return false;
    }else{
      return $filename;
    }
  }
  public function sendMail($mailto)
  {
    sleep(2);
    echo $this->name."#mailto:".$mailto.PHP_EOL;
  }
  public function text_mail($argc,$argv){
    if(!$this->checkEnv($argc)){
      return false;
    }
    $filename = $this->getFileName($argv);
    if(!$filename){
      return false;
    }
    $fp = fopen($filename,'r');
    $counter = 0;
    while(!feof($fp)){
      $line = fgets($fp);
      $mailto = substr($line,0,strlen($line)-1);
      if(preg_match('/^\w+@\w+\.\w+$/',$mailto)){
        $this->sendMail($mailto);
        $counter++;
      }
    }
    return $counter;
  }
  public function redis_mail($mailto){
    if(preg_match('/^\w+@\w+\.\w+$/',$mailto)){
      $this->sendMail($mailto);
    }
  }
}

更多關于PHP相關內容感興趣的讀者可查看本站專題:《PHP進程與線程操作技巧總結》、《PHP網絡編程技巧總結》、《PHP基本語法入門教程》、《PHP數組(Array)操作技巧大全》、《php字符串(string)用法總結》、《php+mysql數據庫操作入門教程》及《php常見數據庫操作技巧匯總》

希望本文所述對大家PHP程序設計有所幫助。

您可能感興趣的文章:
  • PHP實現的多進程控制demo示例
  • 深入探究PHP的多進程編程方法
  • PHP多進程之pcntl_fork的實例詳解
  • PHP使用pcntl_fork實現多進程下載圖片的方法
  • PHP的pcntl多進程用法實例
  • php中實現進程鎖與多進程的方法
  • Linux下實現PHP多進程的方法分享
  • PHP多進程編程總結(推薦)
  • 分享PHP-pcntl 實現多進程代碼
  • php多進程模擬并發事務產生的問題小結
  • PHP多進程通信-消息隊列使用

標簽:文山 黔東 海北 湘西 惠州 梅河口 廈門 濮陽

巨人網絡通訊聲明:本文標題《php多進程應用場景實例詳解》,本文關鍵詞  php,多,進程,應用,場景,實例,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《php多進程應用場景實例詳解》相關的同類信息!
  • 本頁收集關于php多進程應用場景實例詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久久疯狂做爰流白浆xx| 色呦呦国产精品| 爽爽淫人综合网网站| 伊人色综合久久天天人手人婷| 精品国产一区二区国模嫣然| 91精品一区二区三区久久久久久| 欧美在线一区二区三区| 国产精品自拍网站| 精品无人区卡一卡二卡三乱码免费卡| 日韩va欧美va亚洲va久久| 青椒成人免费视频| 国产一区二区久久| 成人综合婷婷国产精品久久免费| 高清在线成人网| www.日韩av| 欧美色视频一区| 精品盗摄一区二区三区| 国产亚洲自拍一区| 中文字幕一区二区三区蜜月 | 欧美日韩视频一区二区| 欧美日韩国产综合久久| 日韩欧美一级二级三级| 久久免费偷拍视频| 男女视频一区二区| 国产成人免费网站| 在线精品视频免费播放| 91精品国产手机| 久久九九99视频| 一区二区在线看| 久久精品久久精品| 99精品热视频| 日韩一区二区中文字幕| 国产精品久久久久婷婷| 日本色综合中文字幕| 成人开心网精品视频| 欧美一卡二卡三卡四卡| 亚洲欧洲色图综合| 美女高潮久久久| 欧美在线短视频| 久久久久高清精品| 日产国产欧美视频一区精品| 成人免费视频caoporn| 欧美另类videos死尸| 亚洲欧洲性图库| 国产一区二区三区久久久| 欧美性极品少妇| 18欧美乱大交hd1984| 狠狠色丁香婷综合久久| 欧美精品日日鲁夜夜添| 亚洲理论在线观看| www.日韩av| 日本一区二区在线不卡| 九一九一国产精品| 91精品福利在线一区二区三区| 亚洲欧洲精品天堂一级| 成人午夜又粗又硬又大| 久久婷婷国产综合国色天香| 午夜天堂影视香蕉久久| 欧美性猛交xxxx黑人交| 亚洲日本丝袜连裤袜办公室| 成人一道本在线| 国产日产欧美精品一区二区三区| 捆绑紧缚一区二区三区视频| 在线成人免费观看| 日韩一区欧美二区| 欧美日韩另类一区| 婷婷中文字幕综合| 精品视频资源站| 亚洲h动漫在线| 欧美在线免费观看亚洲| 亚洲国产aⅴ成人精品无吗| 一本到不卡精品视频在线观看| 国产精品福利电影一区二区三区四区 | 精品久久久久久久久久久院品网| 一区二区免费看| 91久久精品网| 亚洲6080在线| 555www色欧美视频| 一区二区三区精密机械公司| 99re8在线精品视频免费播放| 久久久精品免费观看| 国产在线一区二区| 久久久久久久久久久久电影 | 51精品国自产在线| 亚洲国产欧美一区二区三区丁香婷| 欧美一区二区三区成人| 日韩制服丝袜先锋影音| 91精品福利在线一区二区三区| 日韩高清在线一区| 精品黑人一区二区三区久久| 国产一区二区三区香蕉| 中文一区二区在线观看| 99精品欧美一区二区三区小说| 亚洲精品国产无套在线观| 欧美中文一区二区三区| 麻豆一区二区99久久久久| ww亚洲ww在线观看国产| 成人动漫一区二区| 亚洲va国产va欧美va观看| 欧美一区在线视频| 国产成人综合视频| 亚洲精品第一国产综合野| 欧美亚洲一区二区在线观看| 日本aⅴ亚洲精品中文乱码| 欧美韩国日本不卡| 欧美三级三级三级爽爽爽| 黄色成人免费在线| 亚洲欧洲美洲综合色网| 日韩三级在线免费观看| av中文字幕亚洲| 欧美aaa在线| 亚洲天堂成人在线观看| 日韩一区二区免费电影| 91网站最新网址| 久久精品国产一区二区| 1024成人网色www| 日韩一本二本av| 色综合天天综合狠狠| 国产一二三精品| 亚洲成人动漫av| 国产精品每日更新| 精品国产伦一区二区三区观看体验 | 久久国产人妖系列| 亚洲人成在线观看一区二区| 欧美mv日韩mv国产| 欧美精品日韩一本| 91麻豆免费在线观看| 国产成人亚洲综合a∨婷婷| 亚洲狠狠爱一区二区三区| 国产色产综合色产在线视频| 欧美性做爰猛烈叫床潮| av网站免费线看精品| 国内精品伊人久久久久av一坑| 一区二区三区欧美在线观看| 久久精品一级爱片| 久久婷婷色综合| 《视频一区视频二区| 久久久精品天堂| 久久综合色播五月| 欧美mv和日韩mv的网站| 91精品久久久久久久99蜜桃| 在线亚洲欧美专区二区| 91在线观看视频| 成人免费三级在线| 风间由美一区二区三区在线观看| 国内精品视频一区二区三区八戒| 免费成人小视频| 日韩高清电影一区| 美女被吸乳得到大胸91| 日本大胆欧美人术艺术动态| 亚洲国产成人va在线观看天堂| 洋洋成人永久网站入口| 五月天精品一区二区三区| 亚洲成a人v欧美综合天堂下载| 亚洲女与黑人做爰| 亚洲自拍都市欧美小说| 亚洲国产日韩在线一区模特 | 国产不卡在线播放| 狠狠色综合播放一区二区| 激情小说亚洲一区| 国产一区二区在线影院| 国产91丝袜在线播放0| 高清成人在线观看| 粉嫩嫩av羞羞动漫久久久| 91免费国产在线| 欧美性大战久久久久久久| 欧美一区二区三区在线| 精品蜜桃在线看| 欧美激情一区三区| 一区二区三区高清| 日韩激情一二三区| 国产精一区二区三区| 99re6这里只有精品视频在线观看| 色综合久久中文字幕综合网| 欧美日韩久久久一区| 日韩女优毛片在线| 国产精品理伦片| 亚洲成人av一区二区| 韩国一区二区视频| 91小视频免费看| 欧美一级淫片007| 欧美激情一区二区| 一区二区三区丝袜| 国产一区二区福利视频| 色婷婷久久久久swag精品| 欧美一区二区三区四区在线观看 | 中文字幕一区二区在线播放| 亚洲美女精品一区| 蜜臀久久久久久久| 99久久精品久久久久久清纯| 欧美三区在线视频| 国产丝袜美腿一区二区三区| 午夜精品久久久久久| 风间由美性色一区二区三区| 色综合色狠狠综合色| 欧美高清视频一二三区 | 26uuu亚洲综合色| 亚洲国产日日夜夜| 91同城在线观看| 精品福利一区二区三区免费视频|