精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一個Reentrant Error引發(fā)的對Python信號機制的探索和思考

開發(fā) 后端
前幾天工作時遇到了一個匪夷所思的問題。經(jīng)過幾次嘗試后問題得以解決,但問題產(chǎn)生的原因卻仍令人費解。查找 SO 無果,我決定翻看 Python 的源碼。斷斷續(xù)續(xù)地研究了幾天,終于恍然大悟。撰此文以記。

寫在前面

前幾天工作時遇到了一個匪夷所思的問題。經(jīng)過幾次嘗試后問題得以解決,但問題產(chǎn)生的原因卻仍令人費解。查找 SO 無果,我決定翻看 Python 的源碼。斷斷續(xù)續(xù)地研究了幾天,終于恍然大悟。撰此文以記。

本文環(huán)境:

  • Ubuntu 16.04 (64 bit)
  • Python 3.6.2

使用的 C 源碼可以從 Python 官網(wǎng) 獲取。

起因

工作時用到了 celery 作為異步任務隊列,為方便調(diào)試,我寫了一個腳本用以啟動/關閉 celery 主進程。代碼簡化后如下:

  1. import sys 
  2.  
  3. import subprocess 
  4.  
  5. # ... 
  6.  
  7. celery_process = subprocess.Popen( 
  8.  
  9.     ['celery''-A''XXX''worker'], 
  10.  
  11.     stdout=subprocess.PIPE, 
  12.  
  13.     stderr=sys.stderr 
  14.  
  15.  
  16. try: 
  17.  
  18.     # Start and wait for server process 
  19.  
  20. except KeyboardInterrupt: 
  21.  
  22.     # Ctrl + C pressed 
  23.  
  24.     celery_process.terminate() 
  25.  
  26.     celery_process.wait()  

代碼啟動了 celery worker,并嘗試在捕獲到 KeyboardInterrupt 異常時將其熱關閉。

初看上去沒什么問題。然而實際測試時卻發(fā)生了十分詭異的事情:按下 Ctrl+C 后,程序 偶爾 會拋出這樣的異常:RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>’>。詭異之處有兩點:

異常發(fā)生的時機有隨機性

異常的 traceback 指向 celery 包,也就是說這是在 celery 主進程內(nèi)部發(fā)生的異常

這個結果大大出乎了我的意料。隨機性異常是眾多最難纏的問題之一,因為這常常意味著并發(fā)問題,涉及底層知識,病灶隱蔽,調(diào)試難度大,同時沒有有效的手段判斷問題是否徹底解決(可能只是降低了頻率)。

解決

異常信息中有兩個詞很關鍵:reentrant 和 stdout。reentrant call 說明有一個不可重入的函數(shù)被遞歸調(diào)用了;stdout 則指明了發(fā)生的地點和時機。初步可以判定:由于某種原因,有兩股控制流在同時操控 stdout。

“可重入”是什么?根據(jù) Wikipedia 的定義:如果一個子程序能在執(zhí)行時被中斷并在之后被正確地、安全地喚起,它就被稱為可重入的。依賴于全局數(shù)據(jù)的過程是不可重入的,如 printf(依賴于全局文件描述符)、malloc(依賴與和堆相關的一系列數(shù)據(jù)結構)等函數(shù)。需要注意的是,可重入性(reentrant)與 線程安全性(thread-safe)并不等價,甚至不存在包含關系,Wikipedia 中給出了相關的反例。

多次嘗試后,出現(xiàn)了一條線索:有時候 worker: Warm shutdown (MainProcess) 這個字符串會被二次打印,時機不確定。這句話是 celery 將要熱關閉時的提示語,二次出現(xiàn)只可能是主進程收到了第二個信號。閱讀 celery 的文檔 可知,SIGINT 和 SIGTERM 信號可以引發(fā)熱關閉。回頭瀏覽我的代碼,其中只有一處發(fā)送了 SIGTERM 信號(celery_process.terminate()),至于另一個神秘的信號,我懷疑是 SIGINT。

SO 一下,結果印證了我的猜想:

If you are generating the SIGINT with Ctrl-C on a Unix system, then the signal is being sent to the entire process group.

— via StackOverflow

SIGINT 信號不僅會發(fā)送到父進程,而是會發(fā)到整個進程組,默認情況下包括了所有子進程。也就是說——在攔截了 KeyboardInterrupt 之后執(zhí)行的 celery_process.terminate() 是多此一舉,因為 SIGINT 信號也會被發(fā)送至 celery 主進程,同樣會引起熱關閉。代碼稍作修改即可正常運行:

  1. # ... 
  2.  
  3. try: 
  4.  
  5.     # Start and wait for server process 
  6.  
  7. except KeyboardInterrupt: 
  8.  
  9.     # Ctrl + C pressed 
  10.  
  11.     pass 
  12.  
  13. else
  14.  
  15.     # Signal SIGTERM if no exception raised 
  16.  
  17.     celery_process.terminate() 
  18.  
  19. finally: 
  20.  
  21.     # Wait for it to avoid it becoming orphan 
  22.  
  23.     celery_process.wait()  

猜測

UNIX 信號處理是一個相當奇葩的過程——當進程收到一個信號時,內(nèi)核會選擇一條線程(以一定的規(guī)則),中斷其當前控制流,將控制流強行轉給信號處理函數(shù),待其執(zhí)行完畢后再將控制流交還給原線程。時序圖如下:  

 

由于控制流轉換發(fā)生在同一條線程上,許多線程間同步機制會失效甚至報錯。因此信號處理函數(shù)的編寫要比線程函數(shù)更加嚴格,對同一個文件輸出是被禁止并且無解的,因為很可能會發(fā)生這樣的事情:

 

而且這個問題不能通過加鎖來解決(因為是在同一個線程中,會死鎖)。

因此,我猜測異常發(fā)生時的事件時序是這樣的:在 print 未執(zhí)行完時中斷,又在信號處理函數(shù)中調(diào)用 print,觸發(fā)了重入檢測,引起 RuntimeError: 

疑云又起

不幸的是,我的猜想很快被推翻了。

在翻看 Python signal 模塊的官方文檔,我看到了如下敘述:

A Python signal handler does not get executed inside the low-level (C) signal handler. Instead, the low-level signal handler sets a flag which tells the virtual machine to execute the corresponding Python signal handler at a later point(for example at the next bytecode instruction).

— via Python Documentation

也就是說,Python 中使用 signal.signal 注冊的信號處理函數(shù)并不會在收到信號時立即執(zhí)行,而只是簡單做一個標記,將其延遲至之后的某個時機。這么做可以盡量快地結束異常控制流,減少其對被阻斷進程的影響。

這番表述可以說是推翻了我的猜想,因為 Signal Handler 中的 print 并沒有在異常控制流中執(zhí)行。那異常又是怎么產(chǎn)生的呢?

文檔說 Python Signal Handler 會被延后至某個時機進行,但并沒有明示是什么時候。對于這個疑問,這個提問的被采納回答 則斬釘截鐵地將其具體化到了“某兩個 Python 字節(jié)碼之間”。

我們知道,Python 程序在執(zhí)行前會被編譯成 Python 內(nèi)定的字節(jié)碼

(bytecode),Python 虛擬機實際執(zhí)行的正是這些字節(jié)碼。倘若該回答是正確的,則立即有如下推論:在處理信號的過程中,字節(jié)碼具有原子性(atomic)。也就是說,主線程總是在兩個字節(jié)碼之間決定是否轉移控制流, 而 不會 出現(xiàn)以下情況:

 

這很顯然與我的程序結果相悖:print 與 print 所調(diào)用的 io.BufferedWriter.write 和 io.BufferedWriter.flush 都是用純 C 代碼編寫的,對其的調(diào)用只消耗一條字節(jié)碼(CALL_FUNCTION 或 CALL_FUNCTION_KW),在信號中斷的影響下,這幾個函數(shù)仍保持原子性,在時序圖上互不重疊,更不會發(fā)生重入。

[[203574]] 

因此,除了在兩個字節(jié)碼之間,應該還有其他時機喚起了 Python Signal Handler。

至此,問題已觸及 Python 的地板了,需向更底層挖掘才能找到答案。

深入源碼

信號注冊邏輯位于 Modules/signalmodule.c 文件中。 313 行的 signal_handler 是信號處理函數(shù)的最外層包裝,由系統(tǒng)調(diào)用 signal 或 sigaction 注冊至內(nèi)核,并在信號發(fā)生時被內(nèi)核回調(diào),是異常控制流的入口。signal_handler 主要調(diào)用了 239 行處的 trip_signal 函數(shù),其中有這樣一段代碼:

  1. Handlers[sig_num].tripped = 1;      
  2.  
  3. if (!is_tripped) { 
  4.  
  5.     is_tripped = 1; 
  6.  
  7.     Py_AddPendingCall(checksignals_witharg, NULL); 
  8.  
  9.  

這段代碼便是文檔中所說的邏輯:做標記并延后 Python Signal Handler。其中 checksignals_witharg 即為被延后調(diào)用的函數(shù),位于 192 行,核心代碼只有一句: 

  1. static int 
  2.  
  3. checksignals_witharg(void * unused) 
  4.  
  5.  
  6.     return PyErr_CheckSignals();  
  7.  
  8.  
  9. r_CheckSignals 位于 1511 行:  
  10.  
  11. int 
  12.  
  13. PyErr_CheckSignals(void)  
  14.  
  15.     int i;  
  16.     PyObject *f;   
  17.  
  18.     if (!is_tripped)  
  19.         return 0;  
  20.   
  21.  
  22. #ifdef WITH_THREAD  
  23.     if (PyThread_get_thread_ident() != main_thread)  
  24.         return 0;  
  25. #endif   
  26.  
  27.     is_tripped = 0;   
  28.  
  29.     if (!(f = (PyObject *)PyEval_GetFrame()))  
  30.         f = Py_None;   
  31.  
  32.     for (i = 1; i < NSIG; i++) { 
  33.  
  34.         if (Handlers[i].tripped) {  
  35.             PyObject *result = NULL 
  36.             PyObject *arglist = Py_BuildValue("(iO)", i, f);  
  37.             Handlers[i].tripped = 0;   
  38.  
  39.             if (arglist) {  
  40.                 result = PyEval_CallObject(Handlers[i].func, arglist);  
  41.                 Py_DECREF(arglist);  
  42.             } 
  43.  
  44.             if (!result)  
  45.                 return -1;   
  46.  
  47.             Py_DECREF(result);  
  48.         }  
  49.     }   
  50.  
  51.     return 0;  
  52.  

可見,這個函數(shù)便是異步回調(diào)的最里層,包含了執(zhí)行 Python Signal Handler 的邏輯。

至此我們可以發(fā)現(xiàn),整個 Python 中有兩個辦法可以喚起 Python Signal Handler,一個是調(diào)用 checksignals_witharg,另一個是調(diào)用 PyErr_CheckSignals。前者只是后者的簡單封包。

checksignals_witharg 在 Python 源碼中只出現(xiàn)了一次(不包括定義,下同),沒有被直接調(diào)用的跡象。但需要注意的是,checksignals_witharg 曾被當做 Py_AddPendingCall 的參數(shù),Py_AddPendingCall 所做的工作時將其加入到一個全局隊列中。與之對應的出隊操作是 Py_MakePendingCalls,位于 Python/ceval.c 的 464 行。此函數(shù)會間接調(diào)用 checksignals_witharg,在 Python 源碼中被調(diào)用了 3 次:

  • Modules/_threadmodule.c 52 行的 acquire_timed
  • Modules/main.c 310 行的 run_file
  • Python/ceval.c 722 行的 _PyEval_EvalFrameDefault

值得注意的是,_PyEval_EvalFrameDefault 是一個長達 2600 多行的狀態(tài)機,是解析字節(jié)碼的核心邏輯所在。此處調(diào)用出現(xiàn)于狀態(tài)機主循環(huán)開始處——這印證了上面回答中的部分說法,即 Python 會在兩個字節(jié)碼中間喚起 Python Signal Hanlder。

而 PyErr_CheckSignals 在 Python 源碼中出現(xiàn)了 80 多處,遍布 Python 的各個模塊中——這說明該回答的另一半說法是錯誤的:除了在兩個字節(jié)碼之間,Python 還可能在其他角落喚起 Python Signal Handler。其中有兩處值得注意,它們都位于 Modules/_io/bufferedio.c 中:

  • 1884 行的 _bufferedwriter_flush_unlocked
  • 1939 行的 _io_BufferedWriter_write_impl

這兩個函數(shù)是 io.BufferedWriter 類的底層實現(xiàn),會被 print 間接調(diào)用。仔細觀察可以發(fā)現(xiàn),它們都有著相似的結構:

  1. ENTER_BUFFERED(self)  
  2. // ...  
  3. PyErr_CheckSignals();  
  4. // ...  
  5. LEAVE_BUFFERED(self)  

ENTER_BUFFERED 是一個宏,會嘗試申請無阻塞線程鎖以保證函數(shù)不會被重入:

  1. #define ENTER_BUFFERED(self) \  
  2.     ( (PyThread_acquire_lock(self->lock, 0) ? \  
  3.        1 : _enter_buffered_busy(self)) \  
  4.      && (self->owner = PyThread_get_thread_ident(), 1) )  

[[203575]] 

至此,真相已經(jīng)大白了。

真相

當信號中斷發(fā)生在 _bufferedwriter_flush_unlocked 或 _io_BufferedWriter_write_impl 中時,這兩個函數(shù)中的 PyErr_CheckSignals 會直接喚起 Python Signal Handler,而此時由 ENTER_BUFFERED 上的鎖尚未解開,若 Python Signal Handler 中又有 print 函數(shù)調(diào)用,則會導致再次 ENTER_BUFFERED 上鎖失敗,從而拋出異常。時序圖如下:

 

思考

為什么不將 Python Signal Handler 調(diào)用的地點統(tǒng)一在一個地方,而是散布在程序的各處呢?閱讀相關代碼,我認為有兩點原因:

信號中斷會使某些系統(tǒng)調(diào)用行為異常,從而使系統(tǒng)調(diào)用的調(diào)用者不知如何處理,此時需要調(diào)用 Signal Handler 進行可能的狀態(tài)恢復。一個例子是 write 系統(tǒng)調(diào)用,信號中斷會導致數(shù)據(jù)部分寫回,與此相關的一大批 I/O 函數(shù)(包括出問題的 _bufferedwriter_flush_unlocked 和 _io_BufferedWriter_write_impl)便只能相應地調(diào)用 PyErr_CheckSignals。

某些函數(shù)需要做計算密集型任務,為了防止 Python Signal Handler 的調(diào)用被過長地延后(其實主要是為了及時響應鍵盤中斷,防止程序無法從前臺結束),必須適時地檢查并調(diào)用 Python Signal Handler。一個例子是 Objects/longobject.c 中的諸函數(shù),longobject.c 定義了 Python 特有的無限長整型,其相關的運算可能耗時相當長,必須做這樣的處理。

總結

Python Signal Handler 的調(diào)用會被延后,但時機不止在兩個字節(jié)碼之間,而是可能出現(xiàn)在任何地方。

由于第一條,Python Signal Handler 中盡量都使用 可重入的 的函數(shù),以避免奇怪的問題。可重入性可以從文檔獲知,也可以結合定義由源碼推斷出來。

有疑問,翻源碼。人會說謊,代碼不會。 

責任編輯:龐桂玉 來源: Python開發(fā)者
相關推薦

2025-02-03 07:00:00

2021-12-10 00:01:53

Vsync信號機制

2013-12-19 09:58:36

移動應用產(chǎn)品市場

2011-07-05 18:40:19

QT 信號 機制

2011-07-05 18:32:52

QT 信號 機制

2024-07-16 10:52:09

2021-06-06 16:15:57

地區(qū)接口項目

2024-05-08 10:20:00

Redis分布式

2020-01-06 13:11:30

技術工具

2012-07-10 16:09:54

App盈利

2021-07-27 07:12:11

Getter接口Setter

2011-11-25 13:04:43

空格usr

2022-11-03 07:35:47

OS內(nèi)核異步

2017-03-10 09:33:16

JavaScript類型

2021-09-01 08:58:15

項目 UTFailed

2021-12-01 06:59:27

架構

2024-02-28 08:12:25

SSE接口代理

2010-11-04 09:11:34

Fedora 14評測

2018-12-27 09:09:35

2019-11-04 10:37:53

MongoDB宕機日志
點贊
收藏

51CTO技術棧公眾號

在线看黄色的网站| 精品亚洲一区二区三区四区五区高| 久操视频在线观看免费| 日韩电影大全网站| 国产精品理论片在线观看| 99在线视频免费观看| 最近免费中文字幕大全免费版视频| 日韩精品久久| 亚洲国产精品人久久电影| 日韩欧美黄色大片| 欧美xxxbbb| 国产日韩欧美精品综合| 97神马电影| 亚洲av无码精品一区二区| 欧美91精品| 一区二区三区回区在观看免费视频| 亚洲三级在线视频| 日韩中文影院| 亚洲国产一区视频| 综合视频免费看| 性xxxx视频播放免费| 国内精品写真在线观看| 日本高清久久天堂| 国产亚洲精品码| 99精品全国免费观看视频软件| 亚洲精品第一国产综合精品| 成人性生交视频免费观看| 裤袜国产欧美精品一区| 亚洲成人av电影在线| 免费在线观看污污视频| 国产h在线观看| 99久久国产综合精品女不卡| 999久久久91| 亚洲福利在线播放| 国产一级片中文字幕| 电影亚洲精品噜噜在线观看| 亚洲午夜久久久久中文字幕久| 亚洲图片在线观看| 国产精品毛片一区二区三区四区| 不卡视频免费播放| 99视频免费观看| 99久久久久久久| 激情综合五月婷婷| 国产欧美日韩精品丝袜高跟鞋| 在线观看日本网站| 久久久xxx| 欧洲成人午夜免费大片| 91av在线免费视频| 亚洲日本国产| 久久久伊人日本| 国产精品第72页| 国产精品va| 欧美高清一级大片| 免费毛片在线播放免费| 你懂的国产精品永久在线| 久久视频在线直播| 艳妇荡乳欲伦69影片| 亚洲精品小说| 女人香蕉久久**毛片精品| 欧美在线啊v一区| 少妇激情一区二区三区| 欧美最新精品| 欧美午夜精品一区二区三区| 999精彩视频| 久久福利在线| 91精品国产综合久久久久久 | 理论电影国产精品| 国产欧美一区二区三区视频 | 337p日本欧洲亚洲大胆精品 | 久久香蕉网站| 日韩精品中文字幕视频在线| 丰满少妇高潮一区二区| 成人aaaa| 超碰91人人草人人干| 四虎永久免费在线| 亚洲人成高清| 日韩美女激情视频| 一本到在线视频| 国产成人在线免费观看| 精品网站在线看| 成人激情电影在线看| 蜜桃91麻豆精品一二三区| 狂野欧美一区| 国产主播喷水一区二区| 亚洲国产精品国自产拍久久| www.亚洲在线| 先锋影音亚洲资源| 手机在线免费观看av| 欧美性xxxxx| 日本国产一级片| 亚洲精品黑牛一区二区三区| 日韩高清免费在线| 精品伦精品一区二区三区视频密桃| 亚洲va在线| 欧美一区二区三区四区在线| 一级黄色片网站| 成人av先锋影音| 涩涩涩999| a级片在线免费| 欧美视频中文一区二区三区在线观看 | 亚洲一区久久久| 丝袜视频国产在线播放| ...中文天堂在线一区| 国产av国片精品| 久久精品国产福利| 日韩精品免费综合视频在线播放 | 97在线观看免费观看高清| 黄网站免费久久| 久久精品ww人人做人人爽| 免费高清完整在线观看| 欧美性xxxxx| av漫画在线观看| 日本电影一区二区| 91高潮精品免费porn| 国产毛片久久久久| 国产区在线观看成人精品 | 变态另类ts人妖一区二区| 欧美成人高清| 国产日韩视频在线观看| 国产在线电影| 亚洲h在线观看| 久久综合在线观看| 日韩精品首页| 日韩免费在线免费观看| 日韩在线一区二区三区四区| 亚洲天堂精品在线观看| 男女爽爽爽视频| 日韩美女精品| 97国产在线视频| 亚洲黄色在线播放| 亚洲丝袜精品丝袜在线| 99热一区二区| 日韩精品水蜜桃| 国产精品久久久久久久久久新婚 | 一区二区三区四区视频免费观看| 色偷偷噜噜噜亚洲男人的天堂| 无码人妻丰满熟妇奶水区码| 99视频国产精品| 免费看黄在线看| 啊啊啊国产视频| 九九热这里有精品| 在线性视频日韩欧美| 无码人妻熟妇av又粗又大| 91久色porny| 国产极品粉嫩福利姬萌白酱 | 日韩一区二区三区免费观看| 战狼4完整免费观看在线播放版| 美女黄色成人网| 欧美日本亚洲| 韩日精品一区| 中文字幕欧美国内| 亚洲天堂一二三| 中文字幕制服丝袜一区二区三区 | 精品国产黄a∨片高清在线| 一区二区三区精品99久久| 亚洲 小说区 图片区| 欧美激情一区二区在线| 亚洲国产精品三区| 婷婷综合伊人| 99se婷婷在线视频观看| 色综合999| 亚洲精品一区二区三区蜜桃下载 | 男人的天堂亚洲一区| 视频一区二区在线| 91精品福利观看| 欧美成人精品h版在线观看| 亚洲国产精品国自产拍久久| 亚洲成av人片在线| 香蕉网在线播放| 日本视频在线一区| 日日噜噜夜夜狠狠久久丁香五月 | 美女视频黄频大全不卡视频在线播放| 亚洲欧美日本国产有色| 美女精品久久| 亚洲**2019国产| 国产中文字幕在线视频| 欧美久久久久久蜜桃| 免费在线观看国产精品| 91亚洲国产成人精品一区二区三 | 国产成人综合在线观看| 国产69精品久久久久久久| 国产成人高清| 亚洲影视中文字幕| 91av亚洲| 久久精品视频导航| 欧美 变态 另类 人妖| 18videosex性欧美麻豆| 精品88久久久久88久久久| 国产91精品看黄网站在线观看| 中文天堂在线一区| 成年女人免费视频| 日本成人在线视频网站| 日韩激情视频一区二区| 欧美日韩国产一区二区三区不卡| 91精品国产综合久久久久久丝袜| 成年人黄色大片在线| 色偷偷av亚洲男人的天堂| 蜜桃av鲁一鲁一鲁一鲁俄罗斯的| 日本道精品一区二区三区 | 福利视频在线看| 精品国产精品一区二区夜夜嗨| 波多野结衣在线观看一区| 一区二区三区成人在线视频| a天堂中文字幕| 成人av免费在线观看| 色一情一区二区| 国产精品视区| 欧美黑人在线观看| 欧美成人milf| 欧美日韩视频在线一区二区观看视频| 国产精品一区二区美女视频免费看| 欧美亚洲日本网站| 肉肉视频在线观看| 日韩视频免费在线观看| 你懂的在线观看视频网站| 日韩精品专区在线| 一区二区国产欧美| 91国产免费观看| 影音先锋亚洲天堂| 亚洲一区免费在线观看| 婷婷久久综合网| 国产精品免费观看视频| 国产成人无码精品久久二区三| 成人精品一区二区三区四区| 毛片毛片毛片毛| 日韩精品国产欧美| 欧美久久在线观看| 欧美1级日本1级| 特级西西人体www高清大胆| 四季av一区二区三区免费观看| 欧美午夜精品理论片a级大开眼界 欧美午夜精品久久久久免费视 | 免费黄色片在线观看| 亚洲精品福利视频| 国产成人手机在线| 精品国产青草久久久久福利| 国产99对白在线播放| 欧美日韩高清在线| 怡红院成永久免费人全部视频| 在线观看中文字幕不卡| 无码人妻丰满熟妇区bbbbxxxx| 免费观看欧美大片| 日韩av在线免费观看| 人妻无码中文字幕| 亚洲激情小视频| 三级毛片在线免费看| 日韩电影中文 亚洲精品乱码| 五月婷婷综合久久| 亚洲精品国偷自产在线99热| 污污的视频网站在线观看| 亚洲精品大尺度| 美女做暖暖视频免费在线观看全部网址91 | 亚洲午夜私人影院| 久久精品视频6| 亚洲丶国产丶欧美一区二区三区| 久久网一区二区| 午夜亚洲国产au精品一区二区| 粉嫩aⅴ一区二区三区| 香蕉成人啪国产精品视频综合网| 国产一级18片视频| 欧洲在线/亚洲| 一区二区国产欧美| 精品久久五月天| 污视频网站免费观看| 亚洲欧美日韩天堂一区二区| 高清毛片在线看| 久久久国产精品亚洲一区| 性欧美猛交videos| 国产69精品久久久久99| 亚洲男人av| 国产精品视频精品视频| 宅男噜噜噜66国产精品免费| 91在线观看网站| 亚洲素人在线| 秋霞在线一区二区| 亚洲精品123区| 九色91popny| 国产精品亚洲成人| av无码av天天av天天爽| 国产精品国产成人国产三级| 国产一级aa大片毛片| 欧美性猛交视频| 国产精品午夜福利| 亚洲精品久久久一区二区三区| 九色国产在线观看| 欧美精品一区二区三区国产精品| 蜜桃在线视频| 91在线视频一区| 日韩深夜影院| 黄色a级在线观看| 国产人成精品一区二区三| 天天色综合社区| aaa亚洲精品一二三区| 亚洲女同二女同志奶水| 偷拍日韩校园综合在线| 一级片免费观看视频| 亚洲熟女乱色一区二区三区久久久 | 国内自拍视频一区| 国产精品123区| 警花观音坐莲激情销魂小说| 亚洲欧美日本在线观看| 亚洲二区中文字幕| 日韩伦理在线观看| 26uuu另类亚洲欧美日本老年| 欧美三级电影网址| 欧美精品尤物在线| 黄色工厂这里只有精品| 亚洲性图一区二区| 91在线观看下载| 青青草免费av| 欧美日韩国产一区二区三区地区| 香蕉人妻av久久久久天天| 欧美老女人性生活| 亚洲伦理久久| 日韩视频在线观看国产| 国产精品久久久久久久免费软件| 北条麻妃亚洲一区| 国产精品久久精品日日| 最近免费中文字幕大全免费版视频| 欧美不卡一区二区三区| 免费在线看黄色| 国产精品毛片a∨一区二区三区|国 | 欧美视频一区二区三区| 四虎在线免费观看| 国模视频一区二区三区| 亚洲3区在线| mm131午夜| 国产一区啦啦啦在线观看| 国产精品久久免费观看| 狠狠综合久久av一区二区小说| 丁香花免费高清完整在线播放| 久久好看免费视频| 香蕉久久一区| 天天成人综合网| 日本人妖一区二区| 久操视频在线观看免费| 欧美亚洲国产bt| 日本三级在线视频| 国产精品一二三在线| 青青草国产免费一区二区下载| www日韩视频| 国产精品色婷婷| 97久久人国产精品婷婷| 中文国产亚洲喷潮| 免费视频成人| 在线国产伦理一区| 狠狠网亚洲精品| 欧美日韩三级在线观看| 日韩欧美综合在线| 第一av在线| 久久av二区| 老司机一区二区三区| 91l九色lporny| 欧美日韩亚洲综合在线| 黄色网页在线看| 成人精品一二区| 亚洲茄子视频| 日本成人免费视频| 91精品在线观看入口| 午夜小视频在线观看| 高清一区二区三区视频| 国产毛片一区| 国产精品久久免费观看| 91精品一区二区三区久久久久久| 超碰在线网址| 精品久久蜜桃| 七七婷婷婷婷精品国产| 国产成人综合在线视频| 亚洲国产精品成人av| 456亚洲精品成人影院| 综合av色偷偷网| 国产一级视频在线| 7777精品久久久大香线蕉| 怡红院在线播放| 好吊色欧美一区二区三区| 久久亚洲影院| 国产黄色的视频| 日韩激情av在线免费观看| 全球最大av网站久久| 国产日产欧美一区二区| wwwwxxxxx欧美| 91亚洲精品国偷拍自产在线观看| 欧美国产第二页| 国产一区二区三区四区五区传媒| 中文字幕成人免费视频| 亚洲国产成人av网| av在线电影观看| 国产精品乱子乱xxxx| 蜜桃在线一区二区三区| 国产亚洲色婷婷久久99精品| 夜夜躁日日躁狠狠久久88av| 国产人与zoxxxx另类91| 精品一区二区中文字幕| 亚洲天堂av老司机| 免费黄色片在线观看| 51蜜桃传媒精品一区二区| 久久久水蜜桃av免费网站| 亚洲成人生活片| 在线观看日韩专区| 欧美18免费视频| 中文字幕 日韩 欧美|