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

首頁 > 開發 > PHP > 正文

PHP多進程編程實例說明

2024-05-04 21:47:34
字體:
來源:轉載
供稿:網友

使用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. declare(ticks = 1); 
  2. function signal_handler($signal) {  
  3. print “Caught SIGALRMn”;  
  4. pcntl_alarm(5);  
  5. pcntl_signal(SIGALRM, “signal_handler”, true);  
  6. pcntl_alarm(5); 
  7. for(;;) {  

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

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

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

4.pcntl_fork ( void )

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

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

注意兩點:

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

(2). pcntl_fork間最好不要有其它語句,例如:

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

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

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

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

(2). 非阻塞方式調用,函數還可以在有子進程在運行但沒有結束的子進程時返回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. $pid = pcntl_fork();  
  2. if($pid) {  
  3. pcntl_wait($status);  
  4. $id = getmypid();  
  5. echo “parent process,pid {$id}, child pid {$pid}n”;  
  6. }else{  
  7. $id = getmypid();  
  8. echo “child process,pid {$id}n”;  
  9. sleep(2);  
  10. }  

子進程在輸出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

用來設置信號的回調函數,當父進程退出時,子進程如何得知父進程的退出,當父進程退出時,子進程一般可以通過下面這兩個比較簡單的方法得知父進程已經退出這個消息:

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

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

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

PHP多進程采集數據的例子,代碼如下:

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

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

PHP多進程編程示例2,代碼如下:

  1. //….. 
  2. //需要安裝pcntl的php擴展,并加載它 
  3. if(function_exists(“pcntl_fork”)){ 
  4. //生成子進程 
  5. $pid = pcntl_fork(); 
  6. if($pid == -1){ 
  7. die('could not fork'); 
  8. }else
  9. if($pid){ 
  10. $status = 0; 
  11. //阻塞父進程,直到子進程結束,不適合需要長時間運行的腳本,可使用pcntl_wait($status, 0)實現非阻塞式 
  12. pcntl_wait($status); 
  13. // parent proc code 
  14. exit
  15. }else
  16. // child proc code 
  17. //結束當前子進程,以防止生成僵尸進程 
  18. if(function_exists(“posix_kill”)){ 
  19. posix_kill(getmypid(), SIGTERM); 
  20. }else
  21. system('kill -9'getmypid()); 
  22. exit
  23. }else
  24. // 不支持多進程處理時的代碼在這里 
  25. //….. 

如果不需要阻塞進程,而又想得到子進程的退出狀態,則可以注釋掉pcntl_wait($status)語句,或寫成:

pcntl_wait($status, 1);或 pcntl_wait($status, WNOHANG);

在上面的代碼中,如果父進程退出(使用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)通知內核,自己對子進程的結束不感興趣,那么子進程結束后,內核會回收,并不再給父進程發送信號,例如:

pcntl_signal(SIGCHLD, SIG_IGN);$pid = pcntl_fork();

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

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

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

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

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

怎樣產生僵尸進程的?

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

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

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

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

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

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

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

  1. //Action代碼 
  2. public function createAction(){ 
  3. //…. 
  4. //將args替換成要傳給insertLargeData.php的參數,參數間用空格間隔 
  5. system('nohup php -f insertLargeData.php ' . ' args ' . '&'); 
  6. $this->redirect('/'); 
你還可以使用screen命令代替nohup命令。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久国产一区二区三区| 色综合伊人色综合网| 91av中文字幕| 久久精品国产电影| 亚洲精品久久久久久久久久久| 一本色道久久综合狠狠躁篇怎么玩| 欧美乱大交xxxxx| 欧美亚洲国产日本| 国产精品igao视频| 中文字幕精品—区二区| 欧美日韩国产麻豆| 亚洲丝袜一区在线| 亚洲精品v欧美精品v日韩精品| 国产一区香蕉久久| 日韩av在线免费看| 高清欧美性猛交xxxx黑人猛交| 中文字幕日韩专区| 日韩大胆人体377p| 日韩经典一区二区三区| 国产激情久久久久| 欧美激情欧美激情| 成人免费淫片aa视频免费| 人九九综合九九宗合| 色综合视频一区中文字幕| 最近2019年中文视频免费在线观看| 亚洲一区二区三区视频播放| 在线国产精品视频| 国产精品视频区1| 久久精品国产一区二区电影| 国产精品成人观看视频国产奇米| 欧美性一区二区三区| 中文字幕av一区中文字幕天堂| 亚洲缚视频在线观看| 国产欧美精品va在线观看| 欧美理论电影在线观看| 亚洲精品国产综合久久| 欧美成人午夜剧场免费观看| 成人自拍性视频| 国产日韩欧美日韩大片| 欧美最顶级丰满的aⅴ艳星| 久久国产精品亚洲| 久久久人成影片一区二区三区| 久久久久久久久网站| www.欧美精品一二三区| 国产91在线视频| 久久综合久中文字幕青草| 亚洲人av在线影院| 亚洲成av人片在线观看香蕉| 国内揄拍国内精品少妇国语| 国产剧情久久久久久| 欧美性69xxxx肥| 欧美日韩国产成人在线观看| 成人黄色免费网站在线观看| 91久久久久久久久| 国产欧美中文字幕| 伊人成人开心激情综合网| 日韩国产高清污视频在线观看| 蜜臀久久99精品久久久无需会员| 久久久久国产精品www| 中文字幕日韩综合av| 97国产精品人人爽人人做| 日韩在线观看高清| 狠狠久久五月精品中文字幕| 国产一区在线播放| 国精产品一区一区三区有限在线| 久久夜精品va视频免费观看| 亚洲一区二区三区成人在线视频精品| 国外视频精品毛片| 91中文精品字幕在线视频| 韩日精品中文字幕| 欧美精品午夜视频| 成人精品一区二区三区| 777午夜精品福利在线观看| 久久久久久久久久久网站| 亚洲欧美变态国产另类| 日本国产欧美一区二区三区| 欧美黑人又粗大| 91精品视频免费观看| 国产精品一区=区| 欧美亚洲另类在线| 亚洲精品久久久久国产| 国产精品亚发布| 97超级碰碰人国产在线观看| 在线免费观看羞羞视频一区二区| 亚洲国产精品va在线看黑人| 91在线观看免费高清完整版在线观看| 成人性教育视频在线观看| 在线精品视频视频中文字幕| 亚洲欧美变态国产另类| 国产成人一区二区三区电影| 黑人狂躁日本妞一区二区三区| 欧美精品激情blacked18| 欧美日本啪啪无遮挡网站| 日韩电影大全免费观看2023年上| 欧美精品做受xxx性少妇| 国产亚洲一区二区在线| 久久精品视频亚洲| 日韩av影片在线观看| 欧美大尺度激情区在线播放| 亚洲三级黄色在线观看| 日韩av成人在线| 操日韩av在线电影| 日韩精品高清视频| 57pao国产成人免费| 日韩精品亚洲视频| 亚洲欧美国产制服动漫| 成人在线小视频| 国产精品极品尤物在线观看| 亚洲欧美国产精品专区久久| 欧美韩日一区二区| 欧美一级片久久久久久久| 欧美老女人性生活| 久久精品美女视频网站| 色婷婷av一区二区三区久久| 欧美一级大胆视频| 秋霞成人午夜鲁丝一区二区三区| 久久精品2019中文字幕| 久久韩国免费视频| 亚洲香蕉成人av网站在线观看| 欧美性videos高清精品| yw.139尤物在线精品视频| 成人免费淫片视频软件| 亚洲午夜国产成人av电影男同| 欧美野外猛男的大粗鳮| 国产成人91久久精品| 国产精品中文久久久久久久| 亚洲男人天堂视频| 九九九热精品免费视频观看网站| 亚洲精品一区二区久| 久久精品国产成人精品| 国产一区二区三区久久精品| 亚洲精品成人久久久| 欧美亚洲成人精品| 亚洲一区中文字幕在线观看| 毛片精品免费在线观看| 久久久久免费精品国产| 91久久精品美女| 自拍偷拍免费精品| 国产精品三级久久久久久电影| 九九精品视频在线观看| 成人激情黄色网| 亚洲精品视频网上网址在线观看| 亚洲欧洲一区二区三区在线观看| 日韩av在线网址| 国产精品综合不卡av| 欧洲永久精品大片ww免费漫画| 亚洲精品国产精品国自产在线| 国产亚洲美女精品久久久| 国产一级揄自揄精品视频| 欧美在线观看www| 伊人激情综合网| 亚洲在线一区二区| 国产精品久久久久久久久久ktv| 九九热精品视频在线播放| 日韩免费看的电影电视剧大全| 中文字幕国产亚洲| 国产精品com| 日韩国产高清污视频在线观看| 国产精品扒开腿做爽爽爽男男| 青青草一区二区| 5252色成人免费视频| 欧美福利视频网站| 亚洲区bt下载| 久久久精品亚洲|