校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > 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多進程應用場景實例詳解的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    国产人成一区二区三区影院| 亚洲va国产va欧美va观看| 亚洲精品中文字幕乱码三区| 五月婷婷激情综合网| 高清不卡在线观看| 91精品国产一区二区三区蜜臀| 中文字幕亚洲精品在线观看| 日本vs亚洲vs韩国一区三区| 日本精品视频一区二区三区| 国产亚洲成av人在线观看导航 | 国产亚洲一本大道中文在线| 亚洲国产精品精华液网站| 成人午夜大片免费观看| 91精品国产综合久久精品| 亚洲特黄一级片| 日本高清免费不卡视频| 国产在线精品一区二区夜色| 欧美视频完全免费看| 国产精品二区一区二区aⅴ污介绍| 精品亚洲国产成人av制服丝袜| 91麻豆文化传媒在线观看| 国产精品三级久久久久三级| 国产在线视频不卡二| 日韩女优视频免费观看| 男女男精品视频| 在线不卡中文字幕播放| 一区二区三区精品在线观看| 91网页版在线| 亚洲女与黑人做爰| 91蜜桃婷婷狠狠久久综合9色| 国产精品色哟哟网站| 国产成a人亚洲精品| 国产夜色精品一区二区av| 国产盗摄女厕一区二区三区| 欧美tk—视频vk| 国内成人精品2018免费看| 精品国产91久久久久久久妲己| 美腿丝袜一区二区三区| 日韩欧美亚洲另类制服综合在线 | 亚洲综合一区在线| 欧美中文字幕一区二区三区| 亚洲午夜成aⅴ人片| 欧美三区在线观看| 日韩高清电影一区| 日韩你懂的电影在线观看| 久久精品国产亚洲5555| 久久你懂得1024| 97精品国产97久久久久久久久久久久 | 在线免费不卡视频| 亚洲午夜日本在线观看| 欧美另类久久久品| 玖玖九九国产精品| 国产精品久久久久久福利一牛影视 | 在线成人av网站| 国产资源在线一区| 亚洲视频1区2区| 欧美日韩一区二区三区四区| 日韩主播视频在线| 精品日韩成人av| av在线一区二区三区| 亚洲国产精品久久不卡毛片 | 国产精品色一区二区三区| av在线免费不卡| 日韩精品每日更新| 国产午夜精品美女毛片视频| 91欧美激情一区二区三区成人| 亚洲va韩国va欧美va| 久久久精品影视| 在线观看国产日韩| 另类调教123区 | 日韩精品亚洲专区| 国产欧美日韩卡一| 51精品国自产在线| 不卡区在线中文字幕| 午夜国产精品一区| 国产精品女同一区二区三区| 5月丁香婷婷综合| 99视频精品全部免费在线| 日本少妇一区二区| 中文字幕一区在线| 久久综合999| 欧美夫妻性生活| 色综合久久九月婷婷色综合| 精久久久久久久久久久| 亚洲乱码国产乱码精品精98午夜| 欧美大胆人体bbbb| 欧洲一区二区三区在线| 国产成人在线免费| 久久电影网电视剧免费观看| 成人免费在线视频| 国产亚洲视频系列| 日韩欧美一级在线播放| 欧美日韩在线三区| a亚洲天堂av| 久久国产精品72免费观看| 亚洲一区二区精品久久av| 亚洲欧美综合在线精品| 久久精品免视看| 欧美成人video| 在线不卡欧美精品一区二区三区| 91免费观看在线| www.欧美日韩| 成人精品视频一区二区三区尤物| 久99久精品视频免费观看| 午夜一区二区三区视频| 一区二区三区在线视频免费| 国产精品久久二区二区| 国产精品视频一二| 欧美国产1区2区| 中文字幕免费不卡在线| 国产欧美视频在线观看| 国产亚洲欧美中文| 国产色91在线| 欧美国产亚洲另类动漫| 国产亚洲综合性久久久影院| 久久综合久久久久88| 精品国产123| 亚洲精品在线电影| 久久精品欧美一区二区三区麻豆| 精品久久国产字幕高潮| 日韩女优av电影| 精品毛片乱码1区2区3区| 欧美精品一区二区三区久久久| 久久麻豆一区二区| 欧美国产禁国产网站cc| ㊣最新国产の精品bt伙计久久| 中文字幕一区二区三区在线不卡| 国产精品久久久久一区二区三区 | 美女视频第一区二区三区免费观看网站 | 国产一区二区三区黄视频 | 日韩码欧中文字| 亚洲精品视频自拍| 亚洲一区av在线| 日韩黄色片在线观看| 国产一区不卡视频| 成人黄色大片在线观看| 在线视频你懂得一区二区三区| 91福利资源站| 欧美一区二区三区电影| xfplay精品久久| 国产精品短视频| 视频一区在线播放| 国产一区在线精品| 91蜜桃免费观看视频| 欧美日本一区二区| 久久久久国产精品麻豆ai换脸| 国产精品对白交换视频| 日韩影视精彩在线| 成人视屏免费看| 欧美日韩成人在线| 国产亚洲精品精华液| 亚洲一区二区三区中文字幕| 久久se这里有精品| 91浏览器入口在线观看| 欧美一级在线视频| 亚洲欧美在线aaa| 精品综合免费视频观看| 99九九99九九九视频精品| 欧美一级久久久| 自拍偷自拍亚洲精品播放| 免费成人av在线播放| 91视视频在线观看入口直接观看www | 成人精品视频一区| 欧美精品在线观看一区二区| 欧美国产成人在线| 免费高清成人在线| 色婷婷一区二区| 久久色.com| 蜜臀a∨国产成人精品| 色综合久久88色综合天天| 精品日韩欧美在线| 调教+趴+乳夹+国产+精品| 不卡av在线免费观看| 精品免费日韩av| 午夜一区二区三区视频| voyeur盗摄精品| 久久综合九色综合97婷婷女人| 亚洲五码中文字幕| 91免费看`日韩一区二区| 久久精品日韩一区二区三区| 日本中文字幕不卡| 欧美三级蜜桃2在线观看| 国产精品免费aⅴ片在线观看| 免费xxxx性欧美18vr| 欧美日韩亚洲综合在线 欧美亚洲特黄一级 | 欧美丰满美乳xxx高潮www| 日韩毛片在线免费观看| 成人aa视频在线观看| 国产欧美日韩精品a在线观看| 捆绑紧缚一区二区三区视频| 欧美日韩高清一区二区| 亚洲一区二区三区免费视频| 91国在线观看| 亚洲男帅同性gay1069| 成人av在线资源网| 国产精品久久久久久久久久免费看 | 免费亚洲电影在线| 91精品国产综合久久香蕉的特点 | 老司机一区二区| 日韩一区二区三区在线|