亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

以實例全面講解PHP中多進程編程的相關函數的使用

2024-05-04 23:38:50
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了以實例全面講解PHP中多進程編程的相關函數的使用,包括對僵尸進程的處理等方面,極力推薦!需要的朋友可以參考下

PHP有一組進程控制函數(編譯時需要–enable-pcntl與posix擴展),使得php能實現跟c一樣的創建子進程、使用exec函數執行程序、處理信號等功能。

 

 
  1. <?php  
  2. header('content-type:text/html;charset=utf-8' );  
  3.  
  4. // 必須加載擴展  
  5. if (!function_exists("pcntl_fork")) {  
  6. die("pcntl extention is must !");  
  7. }  
  8. //總進程的數量  
  9. $totals = 3;  
  10. // 執行的腳本數量  
  11. $cmdArr = array();  
  12. // 執行的腳本數量的數組  
  13. for ($i = 0; $i < $totals$i++) {  
  14. $cmdArr[] = array("path" => __DIR__ . "/run.php"'pid' =>$i ,'total' =>$totals);  
  15. }  
  16.  
  17. /*  
  18. 展開:$cmdArr  
  19. Array  
  20.  
  21. [0] => Array  
  22.  
  23. [path] => /var/www/html/company/pcntl/run.php  
  24. [pid] => 0  
  25. [total] => 3  
  26.  
  27.  
  28. [1] => Array  
  29.  
  30. [path] => /var/www/html/company/pcntl/run.php  
  31. [pid] => 1  
  32. [total] => 3  
  33.  
  34.  
  35. [2] => Array  
  36.  
  37. [path] => /var/www/html/company/pcntl/run.php  
  38. [pid] => 2  
  39. [total] => 3  
  40.  
  41.  
  42.  
  43. */ 
  44.  
  45. pcntl_signal(SIGCHLD, SIG_IGN); //如果父進程不關心子進程什么時候結束,子進程結束后,內核會回收。  
  46. foreach ($cmdArr as $cmd) {  
  47. $pid = pcntl_fork(); //創建子進程  
  48. //父進程和子進程都會執行下面代碼  
  49. if ($pid == -1) {  
  50. //錯誤處理:創建子進程失敗時返回-1.  
  51. die('could not fork');  
  52. else if ($pid) {  
  53. //父進程會得到子進程號,所以這里是父進程執行的邏輯  
  54. //如果不需要阻塞進程,而又想得到子進程的退出狀態,則可以注釋掉pcntl_wait($status)語句,或寫成:  
  55. pcntl_wait($status,WNOHANG); //等待子進程中斷,防止子進程成為僵尸進程。  
  56. else {  
  57. //子進程得到的$pid為0, 所以這里是子進程執行的邏輯。  
  58. $path = $cmd["path"];  
  59. $pid = $cmd['pid'] ;  
  60. $total = $cmd['total'] ;  
  61. echo exec("/usr/bin/php {$path} {$pid} {$total}")."/n";  
  62. exit(0) ;  
  63. }  
  64. }  
  65. ?>  

使用PHP真正的多進程運行模式,適用于數據采集、郵件群發、數據源更新、tcp服務器等環節。

PHP有一組進程控制函數(編譯時需要 –enable-pcntl與posix擴展),使得php能在*nix系統中實現跟c一樣的創建子進程、使用exec函數執行程序、處理信號等功能。 PCNTL使用ticks來作為信號處理機制(signal handle callback mechanism),可以最小程度地降低處理異步事件時的負載。何謂ticks?Tick 是一個在代碼段中解釋器每執行 N 條低級語句就會發生的事件,這個代碼段需要通過declare來指定。

常用的PCNTL函數 1. pcntl_alarm ( int $seconds )

設置一個$seconds秒后發送SIGALRM信號的計數器

2. pcntl_signal ( int $signo , callback $handler [, bool $restart_syscalls ] )

為$signo設置一個處理該信號的回調函數。下面是一個隔5秒發送一個SIGALRM信號,并由signal_handler函數獲取,然后打印一個“Caught SIGALRM”的例子:

 

 
  1. <?php 
  2. declare(ticks = 1); 
  3.  
  4. function signal_handler($signal) { 
  5. print "Caught SIGALRM/n"
  6. pcntl_alarm(5); 
  7.  
  8. pcntl_signal(SIGALRM, "signal_handler", true); 
  9. pcntl_alarm(5); 
  10.  
  11. for(;;) { 
  12.  
  13. ?> 

3. pcntl_exec ( string $path [, array $args [, array $envs ]] )

在當前的進程空間中執行指定程序,類似于c中的exec族函數。所謂當前空間,即載入指定程序的代碼覆蓋掉當前進程的空間,執行完該程序進程即結束。

 

 
  1. <?php 
  2. $dir = '/home/shankka/'
  3. $cmd = 'ls'
  4. $option = '-l'
  5. $pathtobin = '/bin/ls'
  6.  
  7. $arg = array($cmd$option$dir); 
  8.  
  9. pcntl_exec($pathtobin$arg); 
  10. echo '123'//不會執行到該行 
  11. ?> 

4. pcntl_fork ( void )

為當前進程創建一個子進程,并且先運行父進程,返回的是子進程的PID,肯定大于零。在父進程的代碼中可以用 pcntl_wait(&$status)暫停父進程知道他的子進程有返回值。注意:父進程的阻塞同時會阻塞子進程。但是父進程的結束不影響子進程的運行。

父進程運行完了會接著運行子進程,這時子進程會從執行pcntl_fork()的那條語句開始執行(包括此函數),但是此時它返回的是零(代表這是一個子進程)。在子進程的代碼塊中最好有exit語句,即執行完子進程后立即就結束。否則它會又重頭開始執行這個腳本的某些部分。

注意兩點:

子進程最好有一個exit;語句,防止不必要的出錯;

pcntl_fork間最好不要有其它語句,例如:

 

 
  1. <?php 
  2. $pid = pcntl_fork(); 
  3. //這里最好不要有其他的語句 
  4. if ($pid == -1) { 
  5. die('could not fork'); 
  6. else if ($pid) { 
  7. // we are the parent 
  8. pcntl_wait($status); //Protect against Zombie children 
  9. else { 
  10. // we are the child 
  11. ?> 

5. pcntl_wait ( int &$status [, int $options ] )

阻塞當前進程,只到當前進程的一個子進程退出或者收到一個結束當前進程的信號。使用$status返回子進程的狀態碼,并可以指定第二個參數來說明是否以阻塞狀態調用:

阻塞方式調用的,函數返回值為子進程的pid,如果沒有子進程返回值為-1;

非阻塞方式調用,函數還可以在有子進程在運行但沒有結束的子進程時返回0。

6. pcntl_waitpid ( int $pid , int &$status [, int $options ] )

功能同pcntl_wait,區別為waitpid為等待指定pid的子進程。當pid為-1時pcntl_waitpid與pcntl_wait 一樣。在pcntl_wait和pcntl_waitpid兩個函數中的$status中存了子進程的狀態信息,這個參數可以用于 pcntl_wifexited、pcntl_wifstopped、pcntl_wifsignaled、pcntl_wexitstatus、 pcntl_wtermsig、pcntl_wstopsig、pcntl_waitpid這些函數。

例如:

 

 
  1. <?php 
  2. $pid = pcntl_fork(); 
  3. if($pid) { 
  4. pcntl_wait($status); 
  5. $id = getmypid(); 
  6. echo "parent process,pid {$id}, child pid {$pid}/n"
  7. }else
  8. $id = getmypid(); 
  9. echo "child process,pid {$id}/n"
  10. sleep(2); 
  11. ?> 

子進程在輸出child process等字樣之后sleep了2秒才結束,而父進程阻塞著直到子進程退出之后才繼續運行。

7. pcntl_getpriority ([ int $pid [, int $process_identifier ]] )

取得進程的優先級,即nice值,默認為0,在我的測試環境的linux中(CentOS release 5.2 (Final)),優先級為-20到19,-20為優先級最高,19為最低。(手冊中為-20到20)。

8. pcntl_setpriority ( int $priority [, int $pid [, int $process_identifier ]] )

設置進程的優先級。

9. posix_kill

可以給進程發送信號

10. pcntl_singal

用來設置信號的回調函數

當父進程退出時,子進程如何得知父進程的退出

當父進程退出時,子進程一般可以通過下面這兩個比較簡單的方法得知父進程已經退出這個消息:

當父進程退出時,會有一個INIT進程來領養這個子進程。這個INIT進程的進程號為1,所以子進程可以通過使用getppid()來取得當前父進程的pid。如果返回的是1,表明父進程已經變為INIT進程,則原進程已經推出。

使用kill函數,向原有的父進程發送空信號(kill(pid, 0))。使用這個方法對某個進程的存在性進行檢查,而不會真的發送信號。所以,如果這個函數返回-1表示父進程已經退出。

除了上面的這兩個方法外,還有一些實現上比較復雜的方法,比如建立管道或socket來進行時時的監控等等。

PHP多進程采集數據的例子

 

 
  1. <?php 
  2. /** 
  3. * Project: Signfork: php多線程庫 
  4. * File: Signfork.class.php 
  5. */ 
  6.  
  7. class Signfork{ 
  8. /** 
  9. * 設置子進程通信文件所在目錄 
  10. * @var string 
  11. */ 
  12. private $tmp_path='/tmp/'
  13.  
  14. /** 
  15. * Signfork引擎主啟動方法 
  16. * 1、判斷$arg類型,類型為數組時將值傳遞給每個子進程;類型為數值型時,代表要創建的進程數. 
  17. * @param object $obj 執行對象 
  18. * @param string|array $arg 用于對象中的__fork方法所執行的參數 
  19. * 如:$arg,自動分解為:$obj->__fork($arg[0])、$obj->__fork($arg[1])... 
  20. * @return array 返回 array(子進程序列=>子進程執行結果); 
  21. */ 
  22. public function run($obj,$arg=1){ 
  23. if(!method_exists($obj,'__fork')){ 
  24. exit("Method '__fork' not found!"); 
  25.  
  26. if(is_array($arg)){ 
  27. $i=0; 
  28. foreach($arg as $key=>$val){ 
  29. $spawns[$i]=$key
  30. $i++; 
  31. $this->spawn($obj,$key,$val); 
  32. $spawns['total']=$i
  33. }elseif($spawns=intval($arg)){ 
  34. for($i = 0; $i < $spawns$i++){ 
  35. $this->spawn($obj,$i); 
  36. }else
  37. exit('Bad argument!'); 
  38.  
  39. if($i>1000) exit('Too many spawns!'); 
  40. return $this->request($spawns); 
  41.  
  42. /** 
  43. * Signfork主進程控制方法 
  44. * 1、$tmpfile 判斷子進程文件是否存在,存在則子進程執行完畢,并讀取內容 
  45. * 2、$data收集子進程運行結果及數據,并用于最終返回 
  46. * 3、刪除子進程文件 
  47. * 4、輪詢一次0.03秒,直到所有子進程執行完畢,清理子進程資源 
  48. * @param string|array $arg 用于對應每個子進程的ID 
  49. * @return array 返回 array([子進程序列]=>[子進程執行結果]); 
  50. */ 
  51. private function request($spawns){ 
  52. $data=array(); 
  53. $i=is_array($spawns)?$spawns['total']:$spawns
  54. for($ids = 0; $ids<$i$ids++){ 
  55. while(!($cid=pcntl_waitpid(-1, $status, WNOHANG)))usleep(30000); 
  56. $tmpfile=$this->tmp_path.'sfpid_'.$cid
  57. $data[$spawns['total']?$spawns[$ids]:$ids]=file_get_contents($tmpfile); 
  58. unlink($tmpfile); 
  59. return $data
  60.  
  61. /** 
  62. * Signfork子進程執行方法 
  63. * 1、pcntl_fork 生成子進程 
  64. * 2、file_put_contents 將'$obj->__fork($val)'的執行結果存入特定序列命名的文本 
  65. * 3、posix_kill殺死當前進程 
  66. * @param object $obj 待執行的對象 
  67. * @param object $i 子進程的序列ID,以便于返回對應每個子進程數據 
  68. * @param object $param 用于輸入對象$obj方法'__fork'執行參數 
  69. */ 
  70. private function spawn($obj,$i,$param=null){ 
  71. if(pcntl_fork()===0){ 
  72. $cid=getmypid(); 
  73. file_put_contents($this->tmp_path.'sfpid_'.$cid,$obj->__fork($param)); 
  74. posix_kill($cid, SIGTERM); 
  75. exit
  76. ?> 

php在pcntl_fork()后生成的子進程(通常為僵尸進程)必須由pcntl_waitpid()函數進行資源釋放。但在 pcntl_waitpid()不一定釋放的就是當前運行的進程,也可能是過去生成的僵尸進程(沒有釋放);也可能是并發時其它訪問者的僵尸進程。但可以使用posix_kill($cid, SIGTERM)在子進程結束時殺掉它。

子進程會自動復制父進程空間里的變量。

PHP多進程編程示例2

 

 
  1. <?php 
  2. //..... 
  3. //需要安裝pcntl的php擴展,并加載它 
  4. if(function_exists("pcntl_fork")){ 
  5. //生成子進程 
  6. $pid = pcntl_fork(); 
  7. if($pid == -1){ 
  8. die('could not fork'); 
  9. }else
  10. if($pid){ 
  11. $status = 0; 
  12. //阻塞父進程,直到子進程結束,不適合需要長時間運行的腳本,可使用pcntl_wait($status, 0)實現非阻塞式 
  13. pcntl_wait($status); 
  14. // parent proc code 
  15. exit
  16. }else
  17. // child proc code 
  18. //結束當前子進程,以防止生成僵尸進程 
  19. if(function_exists("posix_kill")){ 
  20. posix_kill(getmypid(), SIGTERM); 
  21. }else
  22. system('kill -9'getmypid()); 
  23. exit
  24. }else
  25. // 不支持多進程處理時的代碼在這里 
  26. //..... 
  27. ?> 
  28. 如果不需要阻塞進程,而又想得到子進程的退出狀態,則可以注釋掉pcntl_wait($status)語句,或寫成: 
  29.  
  30. <?php 
  31. pcntl_wait($status, 1); 
  32. //或 
  33. pcntl_wait($status, WNOHANG); 
  34. ?> 

在上面的代碼中,如果父進程退出(使用exit函數退出或redirect),則會導致子進程成為僵尸進程(會交給init進程控制),子進程不再執行。

僵尸進程是指的父進程已經退出,而該進程dead之后沒有進程接受,就成為僵尸進程.(zombie)進程。任何進程在退出前(使用exit退出) 都會變成僵尸進程(用于保存進程的狀態等信息),然后由init進程接管。如果不及時回收僵尸進程,那么它在系統中就會占用一個進程表項,如果這種僵尸進程過多,最后系統就沒有可以用的進程表項,于是也無法再運行其它的程序。

預防僵尸進程有以下幾種方法:

1. 父進程通過wait和waitpid等函數使其等待子進程結束,然后再執行父進程中的代碼,這會導致父進程掛起。上面的代碼就是使用這種方式實現的,但在WEB環境下,它不適合子進程需要長時間運行的情況(會導致超時)。

使用wait和waitpid方法使父進程自動回收其僵尸子進程(根據子進程的返回狀態),waitpid用于臨控指定子進程,wait是對于所有子進程而言。

2. 如果父進程很忙,那么可以用signal函數為SIGCHLD安裝handler,因為子進程結束后,父進程會收到該信號,可以在handler中調用wait回收

3. 如果父進程不關心子進程什么時候結束,那么可以用signal(SIGCHLD, SIG_IGN)通知內核,自己對子進程的結束不感興趣,那么子進程結束后,內核會回收,并不再給父進程發送信號,例如:

 

 
  1. <?php 
  2. pcntl_signal(SIGCHLD, SIG_IGN); 
  3. $pid = pcntl_fork(); 
  4. //....code 
  5. ?> 

4. 還有一個技巧,就是fork兩次,父進程fork一個子進程,然后繼續工作,子進程再fork一個孫進程后退出,那么孫進程被init接管,孫進程結束后,init會回收。不過子進程的回收還要自己做。下面是一個例子:

 

 
  1. #include "apue.h" 
  2. #include <sys/wait.h> 
  3.  
  4. int main(void){ 
  5. pid_t pid; 
  6.  
  7. if ((pid = fork()) < 0){ 
  8. err_sys("fork error"); 
  9. else if (pid == 0){ /**//* first child */ 
  10. if ((pid = fork()) < 0){ 
  11. err_sys("fork error"); 
  12. }elseif(pid > 0){ 
  13. exit(0); /**//* parent from second fork == first child */ 
  14.  
  15. /** 
  16. * We're the second child; our parent becomes init as soon 
  17. * as our real parent calls exit() in the statement above. 
  18. * Here's where we'd continue executing, knowing that when 
  19. * we're done, init will reap our status. 
  20. */ 
  21. sleep(2); 
  22. printf("second child, parent pid = %d ", getppid()); 
  23. exit(0); 
  24.  
  25. if (waitpid(pid, NULL, 0) != pid) /**//* wait for first child */ 
  26. err_sys("waitpid error"); 
  27.  
  28. /** 
  29. * We're the parent (the original process); we continue executing, 
  30. * knowing that we're not the parent of the second child. 
  31. */ 
  32. exit(0); 

在fork()/execve()過程中,假設子進程結束時父進程仍存在,而父進程fork()之前既沒安裝SIGCHLD信號處理函數調用 waitpid()等待子進程結束,又沒有顯式忽略該信號,則子進程成為僵尸進程,無法正常結束,此時即使是root身份kill-9也不能殺死僵尸進程。補救辦法是殺死僵尸進程的父進程(僵尸進程的父進程必然存在),僵尸進程成為”孤兒進程”,過繼給1號進程init,init會定期調用wait回收清理這些父進程已退出的僵尸子進程。

所以,上面的示例可以改成:

 

  1. <?php 
  2. //..... 
  3. //需要安裝pcntl的php擴展,并加載它 
  4. if(function_exists("pcntl_fork")){ 
  5. //生成第一個子進程 
  6. $pid = pcntl_fork(); //$pid即所產生的子進程id 
  7. if($pid == -1){ 
  8. //子進程fork失敗 
  9. die('could not fork'); 
  10. }else
  11. if($pid){ 
  12. //父進程code 
  13. sleep(5); //等待5秒 
  14. exit(0); //或$this->_redirect('/'); 
  15. }else
  16. //第一個子進程code 
  17. //產生孫進程 
  18. if(($gpid = pcntl_fork()) < 0){ ////$gpid即所產生的孫進程id 
  19. //孫進程產生失敗 
  20. die('could not fork'); 
  21. }elseif($gpid > 0){ 
  22. //第一個子進程code,即孫進程的父進程 
  23. $status = 0; 
  24. $status = pcntl_wait($status); //阻塞子進程,并返回孫進程的退出狀態,用于檢查是否正常退出 
  25. if($status ! = 0) file_put_content('filename''孫進程異常退出'); 
  26. //得到父進程id 
  27. //$ppid = posix_getppid(); //如果$ppid為1則表示其父進程已變為init進程,原父進程已退出 
  28. //得到子進程id:posix_getpid()或getmypid()或是fork返回的變量$pid 
  29. //kill掉子進程 
  30. //posix_kill(getmypid(), SIGTERM); 
  31. exit(0); 
  32. }else//即$gpid == 0 
  33. //孫進程code 
  34. //.... 
  35. //結束孫進程(即當前進程),以防止生成僵尸進程 
  36. if(function_exists('posix_kill')){ 
  37. posix_kill(getmypid(), SIGTERM); 
  38. }else
  39. system('kill -9'getmypid()); 
  40. exit(0); 
  41. }else
  42. // 不支持多進程處理時的代碼在這里 
  43. //..... 
  44. ?> 

怎樣產生僵尸進程的

一個進程在調用exit命令結束自己的生命的時候,其實它并沒有真正的被銷毀,而是留下一個稱為僵尸進程(Zombie)的數據結構(系統調用exit,它的作用是使進程退出,但也僅僅限于將一個正常的進程變成一個僵尸進程,并不能將其完全銷毀)。在Linux進程的狀態中,僵尸進程是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,僵尸進程不再占有任何內存空間。它需要它的父進程來為它收尸,如果他的父進程沒安裝SIGCHLD信號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該信號,那么它就一直保持僵尸狀態,如果這時父進程結束了,那么init進程自動會接手這個子進程,為它收尸,它還是能被清除的。但是如果如果父進程是一個循環,不會結束,那么子進程就會一直保持僵尸狀態,這就是為什么系統中有時會有很多的僵尸進程。

任何一個子進程(init除外)在exit()之后,并非馬上就消失掉,而是留下一個稱為僵尸進程(Zombie)的數據結構,等待父進程處理。這是每個子進程在結束時都要經過的階段。如果子進程在exit()之后,父進程沒有來得及處理,這時用ps命令就能看到子進程的狀態是”Z”。如果父進程能及時 處理,可能用ps命令就來不及看到子進程的僵尸狀態,但這并不等于子進程不經過僵尸狀態。

如果父進程在子進程結束之前退出,則子進程將由init接管。init將會以父進程的身份對僵尸狀態的子進程進行處理。

另外,還可以寫一個php文件,然后在以后臺形式來運行它,例如:

 

 
  1. <?php 
  2. //Action代碼 
  3. public function createAction(){ 
  4. //.... 
  5. //將args替換成要傳給insertLargeData.php的參數,參數間用空格間隔 
  6. system('php -f insertLargeData.php ' . ' args ' . '&'); 
  7. $this->redirect('/'); 
  8. ?> 

然后在insertLargeData.php文件中做數據庫操作。也可以用cronjob + php的方式實現大數據量的處理。

如果是在終端運行php命令,當終端關閉后,剛剛執行的命令也會被強制關閉,如果你想讓其不受終端關閉的影響,可以使用nohup命令實現:

 

 
  1. <?php 
  2. //Action代碼 
  3. public function createAction(){ 
  4. //.... 
  5. //將args替換成要傳給insertLargeData.php的參數,參數間用空格間隔 
  6. system('nohup php -f insertLargeData.php ' . ' args ' . '&'); 
  7. $this->redirect('/'); 
  8. ?> 

你還可以使用screen命令代替nohup命令。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲成色777777在线观看影院| 国产精品激情av电影在线观看| 自拍偷拍免费精品| 欧美最近摘花xxxx摘花| 亚洲激情视频网站| 国产91精品高潮白浆喷水| www.亚洲免费视频| 亚洲欧美日本另类| 中文字幕欧美日韩va免费视频| 社区色欧美激情 | 国产精品视频成人| 欧美在线视频网站| 中文字幕精品一区久久久久| 亚洲综合在线播放| 国产精品99久久久久久人| 欧美一级片免费在线| 成人午夜激情免费视频| 久久噜噜噜精品国产亚洲综合| 97视频在线观看亚洲| 狠狠躁夜夜躁人人躁婷婷91| 国产精品久久久久久av下载红粉| 97在线免费观看视频| 91精品国产自产在线| 国产小视频91| 国产精品成人在线| 国产视频精品一区二区三区| 日韩精品欧美国产精品忘忧草| 中文字幕欧美精品在线| 91久久精品国产| 日本精品视频在线观看| 国产精品入口日韩视频大尺度| 国产一区二区视频在线观看| 亚洲精品国产精品乱码不99按摩| 亚洲va久久久噜噜噜久久天堂| 中文字幕亚洲欧美日韩在线不卡| 久久久精品国产| 91九色蝌蚪国产| 亚洲精品一区久久久久久| 欧美猛少妇色xxxxx| 亚洲精品免费av| 欧美亚洲日本黄色| 久久久极品av| 日韩av在线资源| 亚洲一区久久久| 欧美日韩精品中文字幕| 庆余年2免费日韩剧观看大牛| 亚洲日本aⅴ片在线观看香蕉| 国产日韩欧美一二三区| 国产精品久久精品| 91久久夜色精品国产网站| 国产精品福利在线| 亚洲伊人第一页| 久久精品电影网站| 亚洲欧美成人一区二区在线电影| 91精品国产91久久久久久久久| 久久久人成影片一区二区三区| 成人做爽爽免费视频| 欧美一二三视频| 国产精自产拍久久久久久| 亚洲第一级黄色片| 91免费观看网站| 亚洲欧洲国产精品| 91精品国产成人www| 亚洲天堂av在线免费观看| 中文字幕精品在线视频| 国内精品模特av私拍在线观看| 欧美裸体男粗大视频在线观看| 亚洲国产小视频在线观看| 国产不卡av在线免费观看| 在线观看国产欧美| 精品国产一区二区三区久久狼黑人| 欧美综合激情网| 免费av在线一区| 日本免费在线精品| 欧美日韩国产综合视频在线观看中文| 高清在线视频日韩欧美| 国产欧美精品久久久| 国产精品视频999| 久久久久这里只有精品| 日本一区二区在线免费播放| 色与欲影视天天看综合网| 国产精品白嫩初高中害羞小美女| 夜夜狂射影院欧美极品| 午夜免费在线观看精品视频| 日韩视频在线观看免费| 欧美亚洲在线观看| 北条麻妃一区二区在线观看| 亚洲免费视频观看| 91热精品视频| 色综合老司机第九色激情| 欧美日韩aaaa| 视频一区视频二区国产精品| 国产精品久久不能| 久久69精品久久久久久久电影好| 色综合伊人色综合网| 国产精品久久久久秋霞鲁丝| 欧美日韩另类字幕中文| 久久99精品久久久久久噜噜| 在线视频日韩精品| 欧美亚洲第一区| 亚洲精品美女在线| 亚洲一区二区久久久久久久| 九九精品在线视频| 国产精品一区二区三区久久| 亚洲第一视频网站| 欧美精品aaa| 亚洲美女av电影| 97婷婷大伊香蕉精品视频| 亚洲国产古装精品网站| 久久亚洲精品国产亚洲老地址| 国产精品男女猛烈高潮激情| 大荫蒂欧美视频另类xxxx| 久久免费视频在线观看| 国产视频欧美视频| 国产小视频国产精品| 久久久91精品国产一区不卡| 少妇精69xxtheporn| 久久人人看视频| 久久精品色欧美aⅴ一区二区| 日韩欧美亚洲一二三区| 92国产精品视频| 久久99热精品这里久久精品| 久久国产精品久久久久久| 成人av番号网| 51色欧美片视频在线观看| 欧美日韩裸体免费视频| 亚洲激情在线观看| 国产精品18久久久久久首页狼| 国产成人av在线播放| 亚洲免费小视频| 久久久久九九九九| 国产视频精品自拍| 久久在精品线影院精品国产| 欧美在线性爱视频| 久久久欧美一区二区| 91国在线精品国内播放| 欧洲成人性视频| 久久久精品国产亚洲| 久久久999成人| 欧美日韩国产中文字幕| 亚州国产精品久久久| 成人国产亚洲精品a区天堂华泰| 久久久久亚洲精品| 欧美日韩色婷婷| 国产精品久久久久久久久久久久久| 亚洲男人天堂2019| 中文字幕亚洲专区| 欧美激情亚洲另类| 久久精品99久久香蕉国产色戒| 亚洲黄色www| 欧美日韩免费看| 亚洲日本欧美日韩高观看| 国产精品毛片a∨一区二区三区|国| 久久韩国免费视频| 中文字幕亚洲无线码在线一区| 国产男人精品视频| 久久久精品一区二区三区| 97国产精品视频人人做人人爱| 欧美电影在线观看完整版| 欧美国产视频日韩| 精品一区二区三区四区在线| 国产精品欧美在线| 最近中文字幕2019免费| 亚洲影院污污.|