一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Perl進(jìn)程(Processes)、管道(Pipes)和信號(hào)(Signals)之信號(hào)

 vclyin 2012-04-20

本系列文章討論P(yáng)erl的三個(gè)關(guān)鍵功能:進(jìn)程(Processes)、管道(Pipes)信號(hào)(Signals)。通過建立一個(gè)新進(jìn)程,Perl程序可以運(yùn)行另一個(gè)程序甚至是它自己的拷貝。管道允許Perl腳本剛其它進(jìn)行交換數(shù)據(jù),而信號(hào)使Perl腳本監(jiān)視和控制其它進(jìn)程成為可能。本文討論的是其中的:信號(hào)。

信號(hào)( signal

正如文件句柄,理解信號(hào)是網(wǎng)絡(luò)編程的基礎(chǔ)。信號(hào)是通過操作系統(tǒng)發(fā)送給你的程序的一個(gè)消息,告訴它發(fā)生了重要的事情。信號(hào)可以指示程序自身的一個(gè)錯(cuò)誤,比如嘗試除0。事件要求立刻反應(yīng),例如用戶嘗試終止這個(gè)程序,或者一個(gè)非關(guān)鍵信息,如程序啟動(dòng)后,終止一個(gè)子進(jìn)程。
除了由操作系統(tǒng)發(fā)送之外,進(jìn)程間也可以發(fā)送消息。例如,當(dāng)用戶按下 Ctrl + C 鍵時(shí),發(fā)送一個(gè)中斷信號(hào)(interrupt signal)給當(dāng)前正在運(yùn)行的程序,這個(gè)信號(hào)不是由操作系統(tǒng)發(fā)出,而是由shell(終端,命令提示符)處理并解析組合鍵。當(dāng)然,一個(gè)進(jìn)程給自己發(fā)信號(hào)也是可能的。

常見信號(hào)

POSIX標(biāo)準(zhǔn)定義了19個(gè)信號(hào)。每一個(gè)信號(hào)都擁有一個(gè)小的整數(shù)和一個(gè)符號(hào)名。我們?cè)谙旅娴谋砀耧@示它們。
表格的第三列表示,當(dāng)一個(gè)進(jìn)程接收到這個(gè)信號(hào)時(shí),會(huì)發(fā)生什么,有些信號(hào)什么都不做。其它的則有些會(huì)立刻中斷進(jìn)程、有的則終止進(jìn)程并導(dǎo)致主存儲(chǔ)器信息轉(zhuǎn)存。大部分信號(hào)可以被“捕獲”。就是說,當(dāng)接收到信號(hào)時(shí),程序可以搭配一個(gè)句柄給信號(hào)并采取對(duì)應(yīng)的處理。但是,有些信號(hào)不能用這種方式攔截。
你不需要完全明白下表中的信號(hào)列表,因?yàn)橛行┎⒉辉赑erl腳本中發(fā)生,或者它們?cè)赑erl自身內(nèi)部用于標(biāo)示底層BUG你沒有辦法做任何相關(guān)的事。當(dāng)然,一大把信號(hào)是相對(duì)常見的,并且我們馬上就能看到它們的詳細(xì)信息。
HUP 信號(hào)是個(gè)掛斷事件。它通常在一個(gè)用戶從命令行運(yùn)行程序 ,然后關(guān)閉命令行窗口或退出解析器時(shí)發(fā)生。這個(gè)信號(hào)的默認(rèn)行為是結(jié)束這個(gè)程序。
INT 信號(hào)是個(gè)用戶發(fā)送的中斷信號(hào)。它通常是在用戶按下中斷鍵(通常是Ctrl + C)時(shí)發(fā)生。這個(gè)信號(hào)的默認(rèn)行為是結(jié)束這個(gè)程序。 QUITINT 相似,但但會(huì)促使程序生成核心文件(在Unix系統(tǒng))。當(dāng)用戶按下“退出”鍵(通常是 Ctrl + \)時(shí)觸發(fā)該信號(hào)。

信號(hào)名稱 注解 描述
HUP 1 A 掛斷檢測
INT 2 A 從鍵盤中斷
QUIT 3 A 從鍵盤退出
ILL 4 A 非法指令
ABRT 6 C 放棄
FPE 8 C 浮點(diǎn)異常
KILL 9 AF 終止信號(hào)
USR1 10 A 自定義信號(hào)1
SEGV 11 C 無效的內(nèi)存引用
USR2 12 A 自定義信號(hào)2
PIPE 13 A 寫入到管道沒有讀取者
ALRM 14 A 鬧鐘的定時(shí)器信號(hào)
TERM 15 A 終止信號(hào)
CHLD 17 B 子進(jìn)程已終止
CONT 18 E 如果停止則繼續(xù)
STOP 19 DF 停止處理
TSTP 20 D 停止虛擬終端(tty)輸入
TTIN 21 D 后臺(tái)處理虛擬終端(tty)輸入
TTOU 22 D 后臺(tái)處理虛擬終端(tty)輸出
注解:

  • A:默認(rèn)操作是結(jié)束進(jìn)程。
  • B:默認(rèn)操作是忽略該信號(hào)。
  • C:默認(rèn)操作是結(jié)束進(jìn)程和核心轉(zhuǎn)儲(chǔ)。
  • D:默認(rèn)操作是停止該進(jìn)程。
  • E:默認(rèn)操作是恢復(fù)該進(jìn)程。
  • F:信號(hào)無法被捕獲或忽略。

按照慣例, 在一個(gè)進(jìn)程中使用TERMKILL 來結(jié)束另一個(gè)進(jìn)程。默認(rèn)的, TERM讓程序直接結(jié)束,但程序可以搭配一個(gè)信號(hào)句柄給 TERM,用來攔截結(jié)束請(qǐng)求以及可能在退出執(zhí)行一些清理工作。 相比之下,KILL 信號(hào)是無法捕獲的,它會(huì)強(qiáng)制進(jìn)程立刻結(jié)束。比如,當(dāng)UINX系統(tǒng)關(guān)機(jī)時(shí),shutdown(關(guān)機(jī))進(jìn)程首先發(fā)送 TERM 給所有正在運(yùn)行的進(jìn)程,給機(jī)會(huì)給它們進(jìn)行清理。如果少數(shù)進(jìn)程在幾秒后依然在運(yùn)行,那么它將發(fā)送 KILL。
PIPE 信號(hào),當(dāng)一個(gè)程序?qū)懭氲焦艿阑蛱捉幼謺r(shí),遠(yuǎn)程進(jìn)程被關(guān)閉或退出時(shí)發(fā)送。這個(gè)信號(hào)在網(wǎng)絡(luò)應(yīng)用程序中很常見,因此我們可以在處理PIPE異常的時(shí)候檢查它。
ALRM 通常與 alarm() 協(xié)同工作,在某一事先安排的時(shí)間將要來臨的時(shí)候,將信號(hào)發(fā)送給程序。特殊的是, ALRM可以被時(shí)間輸出塊I/O調(diào)用。
CHLD 在你的進(jìn)程啟動(dòng)一個(gè)子進(jìn)程后出現(xiàn),并且子進(jìn)程的狀態(tài)在某種程度上已發(fā)生改變。狀態(tài)的代表性的改變是子進(jìn)程已退出,但每次子進(jìn)程停止或繼續(xù)之后, CHLD 依然產(chǎn)生。
STOPTSTP 兩個(gè)信號(hào)都有停止當(dāng)前進(jìn)程的效果。使進(jìn)程無限期地假死;可以通過發(fā)送 CONT 信號(hào)讓它恢復(fù)。 STOP 通常用于一個(gè)程序停止另一個(gè)程序。當(dāng)用戶在終端按下停止鍵(UNIX系統(tǒng)上是Ctrl+Z)時(shí),產(chǎn)生TSTP 信號(hào)。兩者的另一個(gè)區(qū)別是, TSTP 可以被捕獲,而 STOP 不能被捕獲或忽略。

捕獲信號(hào)

你可以通過在全局哈希 %SIG 中添加一個(gè)信號(hào)句柄來捕獲一個(gè)信號(hào)。使用你想捕獲的信號(hào)名作為哈希的鍵。例如,使用 $SIG{INT} 來獲取或設(shè)置 INT 信號(hào)句柄。使用引用作為值:一個(gè)匿名函數(shù)或指向已命名函數(shù)的引用。例如,下面的例子是一個(gè)設(shè)定 INT 信號(hào)句柄的小腳本。當(dāng)我們按下中斷鍵的時(shí)候,它打印一條短信息并增加計(jì)數(shù)器。腳本如此運(yùn)行下去,直到計(jì)數(shù)到三次中斷,說明真正要結(jié)束了。在下面的例子中,當(dāng)我們按下Ctrl+C時(shí),打印一條“別打斷我!”的信息。

#!/usr/bin/perl
#文件:interrupt.pl #1
##############################################
# (c) 2011 LoRui(i@, www.) #
##############################################

use strict; #2
use warnings;

my $interruptions = 0; #3
$SIG{INT} = \&hanlde_interruptions; #4

while($interruptions < 3) { #5
	print "休息一下……\n"; #6
	sleep 5; #7
} #8

sub hanlde_interruptions { #9
	$interruptions++; #10
	warn "別打斷我!你已經(jīng)打斷我 $interruption 次了!\n"; #11
} #12

來看看這個(gè)腳本的詳細(xì)信息。

  • 1到3行:初始化腳本。開啟嚴(yán)格的語法檢測并聲明一個(gè)名為 $interruptions 的全局計(jì)數(shù)器。這個(gè)計(jì)數(shù)器將保持對(duì) INT 接收次數(shù)的跟蹤。
  • 第4行:設(shè)定 INT 句柄。我們通過設(shè)定 $SIG{INT} 來將 INT 信號(hào)的處理程序關(guān)聯(lián)到 handle_interruptions() 函數(shù)。
  • 5到8行:主循環(huán)。程序的主循環(huán)只是簡單的打印一條信息以及用5為參數(shù)調(diào)用 sleep() 函數(shù)。這會(huì)讓程序暫停5秒鐘,或者直到接收到一個(gè)信號(hào)。它只在計(jì)數(shù)器小于3時(shí)才會(huì)繼續(xù)循環(huán)。
  • 9到12行:信號(hào)處理程序。當(dāng) INT 信號(hào)發(fā)生時(shí),將調(diào)用handle_interruptions() 函數(shù),即使這個(gè)程序此間正在處理別的事情。因此,我們的信號(hào)處理程序讓計(jì)數(shù)器遞增了一次,并打印一條警告。

對(duì)于很短的信號(hào)處理程序,你可以使用匿名函數(shù)進(jìn)行處理。比如,下面的代碼片段和剛剛的行將,但我們不需要給信號(hào)處理程序命名:

$SIG{INT} = sub {
                $interruptions++;
                warn "別打斷我!你已經(jīng)打斷我 $interruption 次了!\n";
                 };

除了引用代碼之外, %SIG 接受兩個(gè)特例。字符串“DEFAULT”恢復(fù)默認(rèn)信號(hào)的行為。例如,將 $SIG{INT} 設(shè)定為“DEFAULT”,將讓 INT 信號(hào)再次結(jié)束當(dāng)前腳本。字符串“IGNORE”將讓該信號(hào)完全被忽略。
不要為前面提到過的 KILLSTOP 設(shè)定信號(hào)處理程序感到緊張。這些信號(hào)既不可以捕獲也不可以忽略,并且它們的默認(rèn)操作將永遠(yuǎn)執(zhí)行。
如果你希望使用相同的方法來捕獲多個(gè)不同的信號(hào),并且希望在處理程序里識(shí)別信號(hào),可以檢查處理程序的第一個(gè)參數(shù),它包含信號(hào)的名字。例如,對(duì)于 INT 信號(hào),其處理將其稱為字符串“INT”:

$SIG{TERM} = $SIG{HUP} = $SIG{INT} = \&handler
sub handler {
   my $sig = shift;
   warn "處理 $sig 信號(hào).\n";
}

處理 PIPE 異常

現(xiàn)在我們擁有了處理PIPE異常所需要的知識(shí)?;叵搿禤erl進(jìn)程、管道和信號(hào)之二:管道》里的示例代碼 write_ten.plread_three.pl中那恐怖的PIPE錯(cuò)誤。write_ten.pl打開一個(gè)到read_three.pl的管道并嘗試向其寫入10行文本,但read_three.pl只期望接受3行之后就退出并結(jié)束管道。write_ten.pl 并不知道到對(duì)方的連接已經(jīng)被關(guān)閉,嘗試寫入第4行的時(shí)候, PIPE 信號(hào)產(chǎn)生了。
現(xiàn)在,我們要修改write_ten.pl,讓它檢測并溫和的處理 PIPE 錯(cuò)誤。

#!/usr/bin/perl
#文件:write_ten_ph.pl #1
##############################################
# (c) 2011 LoRui(i@, www.) #
##############################################

use strict; #2
use warnings;

my $ok = 1; #3
$SIG{PIPE} = sub { undef $ok };
open(PIPE, "| read_three.pl") or die ("無法打開管道:$!");
select PIPE; $| = 1; select STDOUT;

my $count = 0;
for($_ = 1; $ok && $_ <= 10; $_++) {
	warn "寫入第 $_ 行\(zhòng)n";
	print PIPE "這是第 $_ 行\(zhòng)n" and $count++;
	sleep 1;
}

close PIPE or die "無法關(guān)閉管道:$!";
print "共寫入 $count 行文本\n";

$SIG{PIPE} = sub { undef $ok }; 當(dāng)接受到一個(gè)PIPE信號(hào)時(shí),該處理程序?qū)⑷∠?ok的定義,讓其為假。
其他修改是,替換原始版本的 for() 循環(huán)到更加高雅的版本,它同時(shí)檢測$ok。如果$ok為假,退出循環(huán)。當(dāng)我們運(yùn)行修改后的代碼時(shí),可以看到程序正常結(jié)束,而且正確的報(bào)告了成功寫入的行數(shù):

% write_ten_ph.pl
寫入第 1 行
read_three.pl 獲取:這是第 1 行
寫入第 2 行
read_three.pl 獲?。哼@是第 2 行
寫入第 3 行
read_three.pl 獲取:這是第 3 行
寫入第 4 行
共寫入 3 行文本

另一種常用方法是設(shè)置 $SIG{INT} 為“IGNORE”,以完整的忽略 PIPE信號(hào)?,F(xiàn)在,我們的職責(zé)是檢查出了什么錯(cuò),我們可以通過 print() 的返回值進(jìn)行檢測。如果 print() 返回假值,我們退出循環(huán)。
下面的 write_ten_i.pl 代碼展示了這種方法。這個(gè)腳本開始于將 $SIG{INT} 設(shè)定為字符串“IGNORE”,阻止 PIPE 信號(hào)。另外,我們修改了打印循環(huán)體:如果 printf() 成功,我們讓計(jì)數(shù)器遞增,否則我們輸警告并通過 last 退出循環(huán)。

#!/usr/bin/perl
#文件:write_ten_i.pl #1
##############################################
# (c) 2011 LoRui(i@, www.) #
##############################################

use strict; #2
use warnings;

$SIG{PIPE} = 'IGNORE'; #3

open(PIPE, "| read_three.pl") or die "無法打開管道:$!"; #4
select PIPE; $| = 1; select STDOUT; #5

my $count = 0; #6
for(1..10) { #7
	warn "寫入第 $_ 行\(zhòng)n"; #8
	if(print PIPE "這是第 $_ 行\(zhòng)n") { #9
		$count++; #10
	} else { #11
		warn "寫入數(shù)據(jù)時(shí)有錯(cuò)誤發(fā)生:$!\n"; #12
		last; #13
	} #14
	sleep 1; #15
} #16
close PIPE or die "無法關(guān)閉管道:$!"; #17

print "共寫入 $count 行文本\n"; #18

運(yùn)行結(jié)果:

% write_ten_i.pl
寫入第 1 行
read_three.pl 獲取:這是第 1 行
寫入第 2 行
read_three.pl 獲?。哼@是第 2 行
寫入第 3 行
read_three.pl 獲?。哼@是第 3 行
寫入第 4 行
寫入數(shù)據(jù)時(shí)有錯(cuò)誤發(fā)生:Broken pipe
共寫入 3 行文本

注意,如果失敗,錯(cuò)誤信息中的 $! 處將顯示 “Broken pipe”。如果你希望將這個(gè)錯(cuò)誤與其它I/O錯(cuò)誤分別處理,我們可以通過正則表達(dá)式來明確地測試它的值?;蛴酶玫姆椒ǎ和ㄟ^它的數(shù)字值與EPIPE的錯(cuò)誤常量進(jìn)行比對(duì),例如:

use Errno ':POSIX';
...
unless (print PIPE "這是第 $_ 行\(zhòng)n") { # 處理寫入錯(cuò)誤
   last if $! == EPIPE;   # PIPE錯(cuò)誤,終止循環(huán)
   die "I/O 錯(cuò)誤: $!";   # 其它錯(cuò)誤,打印錯(cuò)誤信息
}

發(fā)送信號(hào)

Perl腳本可以使用 kill() 函數(shù)發(fā)送一個(gè)信號(hào)到其它進(jìn)程。

$count = kill($signal, @processes)

kill() 函數(shù)發(fā)送信號(hào)$signal給一個(gè)或多個(gè)進(jìn)程。你可以通過數(shù)字(比如:2)或符號(hào)名(比如: INT)來指定要發(fā)送的信號(hào)。@processes是將信號(hào)發(fā)送過去的一個(gè)或多個(gè)進(jìn)程的PID列表。成功執(zhí)行信號(hào)的進(jìn)程數(shù)將作為 kill() 函數(shù)的結(jié)果返回。

一個(gè)進(jìn)程只能發(fā)送一個(gè)信號(hào)給其它進(jìn)程,并且需要對(duì)應(yīng)的權(quán)限。一般而言,進(jìn)程以普通用戶權(quán)限運(yùn)行,那么該進(jìn)程也只能給普通用戶權(quán)限及普通用戶以下權(quán)限運(yùn)行的進(jìn)程發(fā)送信號(hào)。是的,以root或超級(jí)用戶權(quán)限運(yùn)行的進(jìn)程可以給任何進(jìn)程發(fā)送信號(hào)。
kill() 函數(shù)提供了一些技巧。如果你使用特殊的信號(hào)編號(hào)0,那么 kill() 將返回能發(fā)送信號(hào)的進(jìn)程數(shù),而不會(huì)實(shí)際發(fā)送信號(hào)。如果你使用負(fù)數(shù)作為PID, kill() 將處理該負(fù)數(shù)絕對(duì)值對(duì)應(yīng)的進(jìn)程組ID并將信號(hào)發(fā)送到該組所有的成員。
腳本可以通過傳遞變量 $$sill() 來給自己發(fā)送信號(hào)。該變量保存著當(dāng)前進(jìn)程的ID。例如:

kill INT => $$; # 等效于 kill('INT',$$)

讓慢的系統(tǒng)調(diào)用超時(shí)

當(dāng)Perl執(zhí)行系統(tǒng)調(diào)用時(shí),信號(hào)可能產(chǎn)生。大多數(shù)情況下,Perl自動(dòng)重啟并嚴(yán)密監(jiān)控調(diào)用。
少數(shù)系統(tǒng)調(diào)用不適用此規(guī)則。 sleep() 就是其中之一,它根據(jù)指示數(shù)暫停腳本執(zhí)行對(duì)應(yīng)秒數(shù)。如果一個(gè)信號(hào)中斷 sleep(),它將過早地結(jié)束,返回它完成休眠前的秒數(shù)。sleep() 的這個(gè)屬性很有用,因?yàn)樗梢宰屇_本一直暫停,直到有預(yù)期的事件發(fā)生。

$slept = sleep([$seconds])

根據(jù)指定的秒數(shù)暫停,或一直暫停直到接收到一個(gè)信號(hào)。如果沒有給定參數(shù),該函數(shù)將永遠(yuǎn)暫停。 sleep() 將返回其實(shí)際暫停的秒數(shù)。

另一個(gè)例外是四個(gè)參數(shù)的 select(),它可用于定時(shí)等待,直到一個(gè)或多個(gè)設(shè)定的I/O文件句柄準(zhǔn)備就緒。該函數(shù)將在以后文章中描述。

有時(shí)候,自動(dòng)重啟系統(tǒng)調(diào)用不是你想要的。比如,一個(gè)應(yīng)用程序提示用戶輸入密碼,并嘗試從標(biāo)準(zhǔn)輸入讀取用戶輸入。你可能希望,讀取工作在一段時(shí)間后超時(shí)退出,以避免用戶已離開,程序卻還在等待輸入。下面的代碼片段看上去好像能勝任這個(gè)工作:

my $timed_out = 0; 

$SIG{ALRM} = sub { $timed_out = 1 };

print STDERR "輸入密碼: ";
alarm (5);    # 5秒超時(shí)
my $password = <STDIN>;
alarm (0);

print STDERR "操作已超時(shí)\n" if $timed_out;

這里我們使用 alarm() 函數(shù)來設(shè)計(jì)定時(shí)器。當(dāng)定時(shí)器過期,操作系統(tǒng)生成一個(gè) ALRM信號(hào),我們攔截這個(gè)信號(hào)并進(jìn)行處理:設(shè)置全局變量 $timed_out 為真。在這個(gè)代碼里,我們用5秒超時(shí)來調(diào)用 alarm() 函數(shù),然后從標(biāo)準(zhǔn)輸入讀取一行。讀取完成之后,我們以零為參數(shù)再次調(diào)用 alarm(),以關(guān)閉定時(shí)器。就是說,用戶要在5秒鐘的時(shí)間內(nèi)輸入密碼,否則定時(shí)器將失效,我們也不再重啟該程序。

$seconds_lef = alarm($seconds)

為把 ALRM 信號(hào)在$seconds秒之后傳遞給進(jìn)程做準(zhǔn)備。如果參數(shù)為零,將使定時(shí)器失效。

Perl自動(dòng)重啟使用系統(tǒng)調(diào)用變慢的問題中,包括 <>。即使鬧鐘停止了,我們還停留在<>調(diào)用,等待用戶的鍵盤輸入。
這個(gè)問題的解決方法是使用 eval{} 以及讓 ALRM 成為 local 變量,取消讀取。

print STDERR "輸入密碼: ";
my $password =
  eval {
    local $SIG{ALRM} = sub { die "超時(shí)\n" };
    alarm (5);    # 5秒超時(shí)
    return <STDIN>;
  };
alarm (0);
print STDERR "操作已超時(shí)\n" if $@ =~ /timeout/;

這個(gè)程序中,我們命名 eval{} 塊讓 ALRM處理程序局部化(localize)。eval{} 塊設(shè)定鬧鐘,跟前面一樣,嘗試從 STDIN 讀取。如果在 <> 返回之前已超時(shí),用戶輸入將從eval{} 塊返回,并賦值給 $password。
如果在超時(shí)前完成輸入, ALRM 處理程序?qū)⒈粓?zhí)行。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    暴力性生活在线免费视频| 91欧美亚洲精品在线观看| 国产一区欧美一区日韩一区| 国产精品日韩欧美一区二区| 色哟哟哟在线观看视频| 91精品视频免费播放| 亚洲欧美日韩中文字幕二欧美| 91爽人人爽人人插人人爽| 搡老妇女老熟女一区二区| 扒开腿狂躁女人爽出白浆av| 男人操女人下面国产剧情| 欧美色婷婷综合狠狠爱| 中文字幕日韩欧美理伦片| 亚洲国产精品久久综合网| 国产亚洲欧美日韩精品一区| 日韩三级黄色大片免费观看| 久久99这里只精品热在线| 中文字幕亚洲精品人妻| 人妻人妻人人妻人人澡| 91精品国产综合久久福利| 亚洲妇女黄色三级视频| 中文字幕精品一区二区三| 国产一区二区久久综合| 高清一区二区三区四区五区| 毛片在线观看免费日韩| 久久精品中文字幕人妻中文| 国产一区二区三区av在线| 久久这里只有精品中文字幕| 免费播放一区二区三区四区| 欧美精品久久99九九| 最新日韩精品一推荐日韩精品| 91插插插外国一区二区婷婷| 亚洲精品高清国产一线久久| 国产成人国产精品国产三级| 成年女人下边潮喷毛片免费| 国产精品欧美激情在线播放| 久久99亚洲小姐精品综合| 不卡免费成人日韩精品| 免费福利午夜在线观看| 久久三级国外久久久三级| 久久香蕉综合网精品视频|