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

Go語言中的數據競爭模式

譯文 精選
開發
本文主要基于在Uber的Go monorepo中發現的各種數據競爭模式,分析了其背后的原因與分類,希望能夠幫助更多的Go開發人員,去關注并發代碼的編寫,考慮不同的語言的特性、以及避免由于自身編程習慣所引發的并發錯誤。

近年來,Uber已經開始采用Golang(簡稱Go)作為開發微服務的主要編程語言。目前,其Go monorepo(譯者注:包含多個不同項目的單個倉庫)包含了大約5,000萬行代碼,以及大約2,100個獨特的Go服務。而且,它們都還在持續增長中。

為了實現并發,我們通常會使用go關鍵字,為函數調用添加前綴,以實現異步式的運行調用。在Go中,此類異步函數調用被稱為goroutine。開發人員可以通過創建goroutine(例如,對其他服務的IO或RPC調用),來隱藏延遲。不同的goroutine可以通過消息傳遞,以及共享內存的方式,來傳遞數據。其中,共享內存恰好是Go中最常用的數據通信方式之一。

由于goroutineGo很容易被程序員創建和使用,因此它被認為屬于“輕量級” 。同時,由Go編寫的程序通常會比由其他語言編寫的程序具有更強的并發性。例如,通過掃描數十萬個運行在數據中心的微服務實例,我們發現Go微服務的并發性可達Java微服務的8倍。

當然,更高的并發性也意味著更多潛在的并發錯誤。我們常用數據競爭(data race)來描述當兩個或多個goroutine訪問相同的數據,而且至少有一個處于寫入狀態時,由于它們之間并沒有排序,因此就會發生并發錯誤。總的來說,根據Go自身的相互作用等特點,數據競爭之類的隱蔽錯誤非常容易出現,因此我們應該盡量避免。

最近,我們使用動態數據競爭檢測技術開發了一個系統,專門用來檢測Uber的數據競爭。它在上線的六個月時間內,在我們的Go代碼庫中,檢測到了大約2,000個數據競爭。其中已被開發人員著手修復了的數據競爭約有1,100個。下面,我將向您展示我們已發現的各種常見數據競爭模式。

?

Go在goroutine中通過引用來透明地捕獲自由變量 

Go中的嵌套函數(又名closure)通過引用的方式,透明地捕獲所有自由的變量。程序員通常無需明確指定在closure語法中,需要捕獲哪些自由變量。

這種方式是有別于Java和C++的。Java的lambda僅會根據數值去捕獲,而且他們會有意識地避免并發缺陷。而C++則要求開發人員明確地指明是使用數值、還是引用的捕獲方式。當closure較大時,開發人員并不知道closure內使用的變量是否自由,可否通過引用來捕獲。而由于引用的捕獲、以及goroutine都是并發的,因此Go程序最終可能會因為沒能顯式地執行同步,而對自由變量進行無序的訪問。我們可以通過如下三個示例來證明這一點:

示例1:由循環索引的變量捕獲,而導致數據競爭

圖1A中的代碼顯示了迭代Go的切片作業,并通過ProcessJob函數來處理每個元素的作業。

圖片圖片

圖1A:由循環索引的變量捕獲,而導致數據競爭

在此,開發人員會將厚重的ProcessJob包裝在一個匿名的goroutine中。但是,循環索引變量的作業是通過goroutine內部被引用捕獲的。當goroutine為首次循環迭代而啟動,并訪問作業的變量時,父goroutine中的for循環將在切片中更新相同的循環索引變量作業,并指向切片中的第二個元素,這就會導致數據競爭的出現。此類數據競爭可能發生在數值和引用類型上;切片、數組和映射上;以及循環體中的讀和寫的訪問中。為此,Go推薦了一種編碼習慣,來隱藏和私有化循環體中循環索引的變量。不過,開發人員并不總是能夠遵循這一點。

示例2:由err變量的捕獲,所導致的數據競爭

圖1B:由err變量的捕獲,所導致的數據競爭

Go一直提倡函數有多個返回值。圖1B展示了一種常見的通過返回實際值和錯誤對象,來指示是否存在錯誤的用法。可見,當且僅當錯誤值為nil(空)時,實際的返回值才會被認為是有意義的。因此,我們的通常做法是:將返回的錯誤對象,分配給名為err的變量,然后檢查其是否為空(nilness)。不過,由于我們可以在函數體內調用多個返回錯誤的函數,因此程序每次都會對err變量進行多次賦值,然后進行是否為空的檢查。當開發人員將這個習慣用法與goroutine混合使用時,錯誤變量就會在closure中被引用捕獲。結果,程序對于goroutine中err的讀寫訪問,與隨后對封閉函數(或goroutine的多個實例)中相同的err變量的讀寫操作,就會同時運行。這便導致了數據競爭。

示例3:由已命名的返回變量捕獲,所導致的數據競爭

圖片

圖1C:由已命名的返回變量捕獲,所導致的數據競爭

Go引入了一種被稱為已命名返回值的語法塊。已命名的返回變量被視為在函數頂部定義的變量,其作用域超出了函數體。而沒有參數的return語句,被稱為“裸”命名返回值。由于closure的存在,如果將正常(非裸)的返回與已命名的返回相混合、或在具有命名返回的函數中使用延遲返回,那么就可能會引發數據競爭。在上圖1C中的NamedReturnCallee函數返回了一個整數,而且返回變量被命名為result。根據該語法,函數體的其余部分可以對結果進行直接讀寫,而無需額外聲明。如果函數在第4行返回的是一個裸返回,而由于在第2行被賦值為result=10,那么第13行的調用者將看到其返回值為10。編譯器則會安排將結果復制到retVal。同時,已命名的返回函數也可以使用如第9行所示的標準返回語法。該語法會讓編譯器復制return語句中的返回值20,以分配給已命名的返回變量結果。第6行創建了一個goroutine,它會捕獲已命名的返回變量的結果。在設置該goroutine時,即使是并發專家也可能認為讀取第7行的結果中是安全的,畢竟不存在對同一變量的寫入,而且第9行的語句返回的20是一個常量,它似乎并沒有觸及到已命名的返回變量結果。不過,如前所述,代碼在生成的過程中,會將return 20的語句轉換為寫入結果。此時,一旦我們突然對共享的結果變量進行并發讀寫,就會產生數據競爭的情況。

?

切片會產生難以診斷的數據競爭 

切片(Slices)實際上是一些動態數組和引用類型。在其內部,切片包含了一個指向底層數組的指針、它的當前長度、以及底層數組可以擴展的最大容量。為了便于討論,我們將這些變量統稱為切片的元字段(meta field)。切片上的一種常見操作便是通過追加操作(append operation)來使其增長。當達到其容量限制時,代碼會進行新的分配(例如,對當前的容量翻倍),并更新其對應的元字段。而當一個切片被goroutine并發訪問時,Go會通過互斥鎖(mutex),來保護對它的訪問。

圖片圖片

圖2:即使使用鎖,切片仍會出現數據競爭

在圖2中,開發人員往往以為已經對第6行的切片進行了鎖定保護,便可防止數據競爭的出現。而實際上,當第14行將切片作為參數傳遞給沒有鎖保護的goroutine時,就會產生數據競爭。具體而言,goroutine的調用導致了切片中的元字段從調用處(第14行)被復制到被調用者(第11行)處。考慮到切片屬于引用類型,我們認為在將其傳遞(復制)到被調用者時,會導致數據競爭的發生。不過,由于切片與指針類型不同,畢竟元字段是按照數值復制的,因此該數據競爭的發生概率非常低。

?

并發訪問Go內置的、不安全的線程映射會導致頻繁的數據競爭 

哈希表(或稱映射)是Go中的內置語言功能。不過,它對于線程是不安全的。如果多個goroutine同時訪問同一張哈希表,而且其中至少有一個試圖去修改哈希表(插入或刪除某項)的話,就會產生數據競爭。開發人員往往認為他們可以同時訪問哈希表中的不同項。而實際上,與數組或切片不同,映射(哈希表)是一種稀疏的數據結構,訪問某一個元素就可能會導致訪問另一個元素,如果在同一過程中發生了另一種插入或刪除,那么它將會因為修改了稀疏的數據結構,而導致了數據競爭。

我們甚至觀察到了更為復雜的、由并發映射訪問產生的數據競爭。其原因是同一個哈希表被傳遞到了深度調用路徑,而開發人員忘記了這些調用路徑是通過異步goroutine去改變哈希表的事實。圖3便顯示了此類數據競爭的示例。

圖片

圖3:由于并發映射訪問導致的數據競爭

雖然導致數據競爭的哈希表并非Go獨有,但是以下原因會讓Go更容易發生數據競爭:

  • 由于映射是一種內置的語言結構,因此Go開發人員會比其他語言的開發者更頻繁地使用映射。例如,在我們的Java存儲庫中,每MLoC(Millions of Lines Of Code,數百萬行代碼)里有4,389個映射結構;而在Go中,每MLoC里就有5,950個映射,足足高出了1.34倍。
  • 不同于Java的get和put API,哈希表的訪問語法類似數組訪問語法,雖然易于使用,但是也會意外地與隨機訪問數據結構相混淆。在Go中,我們可以使用table[key]的語法,輕松查詢那些不存在(non-existing)的映射元素。該語法能夠簡單地返回默認值,而不會產生任何錯誤。這種容錯性對于開發者在使用Go的映射時是非常友好的。

?

Go開發人員常在pass-by-value時犯錯并導致non-trivial的數據競爭

Go建議使用pass-by-value的語義,以簡化逃逸分析,并為變量提供更好的棧上分配的機會,進而減少垃圾收集器的壓力。與所有對象皆為引用類型的Java不同,在Go中,對象可以是數值類型(如:結構),也可以是引用類型(如:接口)。由于沒有了語法差異,這會導致諸如:sync.Mutex和sync.RWMutex等數值類型,在同步構造中被錯誤地使用。如果一個函數創建了一個互斥體結構,并通過數值傳遞(pass-by-value)給多個goroutine調用,那么這些goroutine在并發執行時,不同的互斥對象是不會在操作過程中共享內部狀態的。這也就破壞了對于受保護的共享內存區域的互斥訪問特性。請參見如下圖4所示的代碼。

圖片圖片

圖4A:由by-reference或by-pointer的方法調用所引起的數據競爭

圖片圖片

圖4B:sync.Mutex的Lock/Unlock簽名

由于Go語法在指針和數值上調用方法是相同的,因此開發人員往往會忽視m.Lock()正在處理互斥鎖的副本并非指針這一問題。調用者仍然可以在互斥的數值上調用這些API。而且編譯器也會透明地安排傳遞數值的地址。相反,如果沒有此類透明度,該錯誤就能夠會被檢測到,并認定為編譯器類型不匹配的錯誤。

據此,當開發人員意外地實現了一個方法,其中的接收者是指向結構的指針,而不是結構的數值或副本時,那么就會發生與此相反的情況。也就是說,調用該方法的多個goroutine,最終會意外地共享結構相同的內部狀態。而且,調用者也不會意識到數值類型在接收者處被透明地轉換為了指針類型。顯然,這都是開發人員所不愿發生的。

?

消息傳遞(通道)和共享內存的混合使用使代碼變得復雜且易受數據競爭的影響

圖片

圖5:將消息傳遞與共享內存混合時的數據競爭

圖5展示了開發人員使用一個專門為信號和等待準備的通道,通過Future來實現的示例。我們可以通過調用Start()方法來啟動Future,并通過調用Future的Wait()方法,來阻止Future的完成。Start()方法會創建一個goroutine,以執行一個注冊到Future的函數,并記錄其返回值(如:response和err)。如第6行所示,goroutine通過在通道ch上發送一條消息,以向Wait()方法發出Future完成的信號。對稱地,如第11行所示,Wait()方法塊會從通道中獲取相應的消息。

在Go中,上下文攜帶了跨越API邊界和進程之間的截止日期、取消信號和其他請求范圍的數值。這是在微服務中為任務設置時間線的常見模式。由此,Wait()阻止了被取消(第13行)的上下文、或已完成的Future(第11行)。此外,Wait()被包裝在一個select語句(第10行)中,并處于阻止狀態,直到至少有一個選擇arm準備就緒。如果上下文超時,則相應的案例將Future的err字段,在第14行上記錄為ErrCancelled。此時,對于err的寫入與第5行對Future的相同變量的寫入操作,便形成了競爭。

?

Add和Done方法的錯誤放置會導致數據競爭

sync.WaitGroup結構是Go的組同步結構。與C++的barrier的barrier、以及latch的構造不同,WaitGroup中參與者的數量不是在構造時被確定的,而是動態更新的。在WaitGroup對象上,Go允許進行Add(int)、Done()和Wait()三種操作。其中,Add()會增加參與者的計數,而Wait()會處于阻止狀態,直到Done()被調用為count的次數(通常每個參與者一次)。由于在Go中,組同步的使用程度比Java高出1.9倍,因此WaitGroup在Go中常被廣泛地使用。在下圖6中,開發人員打算創建與切片itemId里的元素數量相同的goroutine,且并發處理它們。每個goroutine在不同索引的結果切片、以及在第12行對父功能塊中,記錄其成功或失敗的狀態,直到所有的goroutine已完成。接著,它會依次訪問結果中的所有元素,以計算出被成功處理的數量。

圖片圖片

圖6A:由于WaitGroup.Add()的錯誤放置,導致了數據競爭

為了使該代碼能夠正常工作,我們需要在第12行調用Wait()時,保證wg.Add(1)在調用wg.Wait()之前所執行的次數,也就是注冊參與者的數量,必須等于itemIds的長度。這就意味著wg.Add(1)應該在每個goroutine之前被放置在第5行調用。但是,如果開發人員在第7行錯誤地將wg.Add(1)放置在了goroutine的主體中,它就無法保證在外部函數WaitGrpExample調用Wait()時,完整地執行。據此,在調用Wait()時,被注冊到WaitGroup的itemId的長度就可能會變短。正是出于該原因,Wait()會被提前解除阻止。據此,WaitGrpExample函數則可以從切片結果中開始讀取(即:第13行),而一些goroutine則開始并發寫入同一個切片。

此外,我們還發現過早地在Waitgroup上調用wg.Done(),也會導致數據競爭。下圖6B展示了wg.Done()與Go的defer語句交互的結果。當遇到多個defer語句時,代碼會按照“后進先出”的順序去執行。其中,第9行的wg.Wait()會在doCleanup()運行之前完成。即,父goroutine會在第10行去訪問locationErr,而子goroutine可能仍然在延遲的doCleanup()函數內寫入locationErr(為簡潔起見,在此并未顯示)。

圖片圖片

圖6B:由于WaitGroup.Done()的錯誤放置延遲語句排序,并導致了數據競爭


并發運行測試會導致產品或測試代碼中的數據競爭 

測試是Go的內置功能。在那些后綴為_test.go的文件里,任何前綴為Test的函數,都可以測試由Go構建的系統。如果測試代碼調用了API--testing.T.Parallel(),那么它將與其他同類測試并發運行。我們發現此類并發測試有時會在測試代碼中、有時也會在產品代碼中產生大量的數據競爭。

此外,在單個以Test為前綴的函數中,Go開發人員經常會編寫許多子測試,并通過由Go提供的套件包去執行它們。Go推薦開發人員通過表驅動的測試套件習語(table-driven test suite idiom)去編寫和運行測試套件。據此,我們的開發人員在同一個測試中就編寫了數十、甚至數百個可供系統并發運行的子測試。開發人員以為代碼會執行串行測試,而忘記了在大型復雜測試套件中使用共享對象。此外,當產品級API在缺少線程安全(可能是因為沒有需要)的情況下,被并發調用時,情況就會更加惡化。

?

小結 

在上文中,我們分析了Go語言里的各種數據競爭模式,并對其背后的原因進行了分類。當然,不同的原因也可能會相互作用與影響。下表是對各種問題的匯總。

圖片

圖7:數據競爭待分類

上面討論的主要是基于我們在Uber的Go monorepo中發現的各種數據競爭模式,難免有些掛一漏萬。其實,代碼的交錯覆蓋也可能產生數據競爭模式。希望上述提到的各種經驗能夠幫助更多的Go開發人員,去關注并發代碼的編寫,考慮不同的語言的特性、以及避免由于自身編程習慣所引發的并發錯誤。

原文鏈接:https://eng.uber.com/data-race-patterns-in-go/

?

譯者介紹

陳峻 (Julian Chen),51CTO社區編輯,具有十多年的IT項目實施經驗,善于對內外部資源與風險實施管控,專注傳播網絡與信息安全知識與經驗;持續以博文、專題和譯文等形式,分享前沿技術與新知;經常以線上、線下等方式,開展信息安全類培訓與授課。圖片

責任編輯:薛彥澤 來源: 51CTO
相關推薦

2023-12-21 07:09:32

Go語言任務

2024-04-07 11:33:02

Go逃逸分析

2021-07-15 23:18:48

Go語言并發

2025-04-02 05:23:00

GoChannel數據

2023-11-30 08:09:02

Go語言

2023-07-29 15:03:29

2021-06-08 07:45:44

Go語言優化

2023-01-12 08:52:50

GoroutinesGo語言

2024-03-29 09:12:43

Go語言工具

2023-12-30 18:35:37

Go識別應用程序

2025-03-27 00:45:00

2021-07-13 06:44:04

Go語言數組

2024-01-08 07:02:48

數據設計模式

2023-11-21 15:46:13

Go內存泄漏

2024-05-10 08:36:40

Go語言對象

2023-12-25 09:58:25

sync包Go編程

2025-09-25 17:17:06

GoC++指針

2012-06-15 09:56:40

2024-03-26 11:54:35

編程抽象代碼

2023-01-31 08:48:49

Go語言文件
點贊
收藏

51CTO技術棧公眾號

91免费精品视频| 久久天天躁狠狠躁夜夜躁| 僵尸世界大战2 在线播放| 天堂av资源在线| 日韩精品视频网| 欧美成人自拍视频| 波多野结衣av在线免费观看| 欧美高清xxx| 亚洲电影一级黄| 性欧美.com| 熟妇人妻av无码一区二区三区| 日产欧产美韩系列久久99| 欧美精品在线观看| 91成人在线免费视频| 嫩呦国产一区二区三区av| 黑人巨大精品欧美一区二区免费| 亚洲一区二区在线免费观看| 色窝窝无码一区二区三区| 久久精品国产99国产| 97婷婷涩涩精品一区| 人与动物性xxxx| 亚洲桃色综合影院| 欧美一级二级在线观看| 国产理论在线播放| 99riav视频在线观看| 国产精品日日摸夜夜摸av| 久久99国产精品99久久| 国产精品一区二区人人爽| 免费看的黄色欧美网站| 欧美精品videosex性欧美| 亚洲色图27p| 国产精品欧美在线观看| 精品国产乱码久久久久久久久| 欧美男女交配视频| 最新日韩精品| 性久久久久久久| 韩国黄色一级大片| 亚洲s色大片| 国产午夜精品一区二区三区嫩草 | 一区二区在线不卡| 青青草娱乐在线| 97久久精品人人澡人人爽| 91久久精品www人人做人人爽| 一级淫片免费看| 日韩电影免费一区| 国产成人福利网站| 国产成人精品777777| 精品福利av| 久久久在线免费观看| 国产精品成人免费观看| 亚洲欧美综合久久久| 日韩在线播放视频| 操她视频在线观看| 国产精品99视频| 日韩中文在线中文网三级| 女人裸体性做爰全过| 久久免费精品视频在这里| 一区二区三区四区在线观看视频| 国产特黄级aaaaa片免| 一本色道久久综合狠狠躁的番外| 亚洲欧美国产制服动漫| 久久精品国产亚洲av久| 国产乱码精品一区二区三区四区| 一区二区欧美日韩视频| 日韩精品电影一区二区三区| 欧美3p视频| 久久在线免费视频| 久久久久国产精品夜夜夜夜夜| 欧美国产高清| 久久久久久成人精品| 欧美日韩中文视频| 99成人在线| 日本最新高清不卡中文字幕| 亚洲精品91天天久久人人| 久久激情五月激情| 亚洲sss综合天堂久久| 国产ts人妖调教重口男| eeuss影院一区二区三区| 欧美凹凸一区二区三区视频| 91精品国产综合久久久久久豆腐| 亚洲欧洲成人自拍| 欧美精品一区二区三区三州| 激情都市亚洲| 91麻豆精品国产无毒不卡在线观看| 亚洲精品永久视频| 亚洲ww精品| 日韩av综合网| 91n在线视频| 国内精品久久久久久久影视麻豆 | 日韩一级性生活片| 日韩pacopacomama| 欧美猛男gaygay网站| 国产精品19p| 久草精品在线| 久久久精品999| 天天综合网久久综合网| 老司机一区二区| 国外成人免费视频| 3p在线观看| 亚洲成人av福利| 视色视频在线观看| 欧美电影免费网站| 精品国产一区av| 成人免费a视频| 国产美女视频一区| 日本不卡在线播放| 免费在线看电影| 欧美日韩一级大片网址| 精品人妻一区二区免费视频| 婷婷亚洲五月| 国产999精品久久久影片官网| 国产成人免费看一级大黄| 久久久美女毛片| 久久艹国产精品| 亚洲视频自拍| 国产一区二区久久精品| 国产成人精品一区二三区| 国产伦精品一区二区三区在线观看| 欧美高清视频一区| 羞羞污视频在线观看| 欧美日韩一级视频| 免费一级做a爰片久久毛片潮| 在线欧美福利| aa日韩免费精品视频一| yjizz视频网站在线播放| 欧美午夜久久久| 午夜男人的天堂| 国产精品99一区二区| 成人网欧美在线视频| 1pondo在线播放免费| 一本久道久久综合中文字幕 | 99精品视频播放| а√中文在线天堂精品| 久久综合88中文色鬼| 丰满熟女人妻一区二区三| 久久久蜜臀国产一区二区| 91成人在线观看喷潮教学| 一级毛片精品毛片| 欧美成人精品在线播放| 国产视频第二页| 专区另类欧美日韩| 特黄视频免费观看| 日韩久久精品| 国产精品自在线| 91视频在线观看| 欧美精品亚洲一区二区在线播放| 欧美熟妇激情一区二区三区| 轻轻草成人在线| 五月婷婷综合色| 欧美一区=区三区| 日韩中文字幕在线视频| 国产又大又长又粗| 亚洲视频在线一区观看| 波多野结衣在线免费观看| 在线一区电影| 99中文视频在线| 国产乱码精品一区二三赶尸艳谈| 亚洲成人网久久久| 国产精品久久久久久99| 久久久国际精品| 成人午夜激情av| 97久久夜色精品国产| 91久久久国产精品| 日本高清在线观看视频| 亚洲成人网在线观看| 国产又黄又猛又粗又爽| 国产欧美日韩麻豆91| 亚洲一区视频在线| 91动漫在线看| 欧美色资源站| 国产精品盗摄久久久| 日本三级视频在线观看| 91精品黄色片免费大全| 久久精品99国产精| 北条麻妃国产九九精品视频| 99精品免费在线观看| jizzjizz欧美69巨大| 成人国产精品色哟哟| 国产极品人妖在线观看| 精品一区二区亚洲| 亚洲性在线观看| 夜夜嗨av一区二区三区四季av| 亚洲精品女人久久久| 可以看av的网站久久看| 特色特色大片在线| 日韩激情网站| 成人黄色免费在线观看| 123区在线| 在线观看欧美成人| 午夜免费福利视频| 色88888久久久久久影院按摩| 好吊日在线视频| av电影在线观看一区| 亚洲高清免费在线观看| 伊人久久亚洲美女图片| 视频二区一区| 91夜夜蜜桃臀一区二区三区| 国产精品福利片| 免费污视频在线观看| 中文字幕久精品免费视频| 性猛交xxxx乱大交孕妇印度| 欧美性猛片aaaaaaa做受| 青青操视频在线播放| 国产日本欧美一区二区| 无码人妻丰满熟妇啪啪网站| 日av在线不卡| 国产中文字幕视频在线观看| 中文精品电影| 四虎影院一区二区三区| 精品综合久久88少妇激情| 国产精品爽爽爽| 原纱央莉成人av片| 欧美激情在线视频二区| 精品欧美色视频网站在线观看| 精品视频一区在线视频| www.国产欧美| 欧美日韩高清影院| av毛片在线免费观看| 亚洲高清中文字幕| 国产老头老太做爰视频| 国产精品素人一区二区| 新91视频在线观看| a美女胸又www黄视频久久| 男女视频在线观看网站| 青草国产精品久久久久久| 成熟了的熟妇毛茸茸| 欧美日韩精品| 91九色国产ts另类人妖| 欧美独立站高清久久| 日韩中文字幕av在线| 少妇一区二区三区| 国产欧美一区二区三区另类精品| 久久精品九色| 亚洲在线免费视频| 永久免费观看精品视频| 成人黄色短视频在线观看| 97精品国产99久久久久久免费| 欧美怡红院视频一区二区三区| 91av久久| 欧美亚洲国产日本| 忘忧草在线日韩www影院| 久久免费国产精品1| 国产偷倩在线播放| 久久久久久久国产精品| www中文字幕在线观看| 欧美国产极速在线| 欧美理论片在线播放| 久久久久久久久久久久av| 麻豆蜜桃在线| 97精品一区二区视频在线观看| 91九色在线播放| 欧美亚洲成人xxx| 日日av拍夜夜添久久免费| 日韩免费黄色av| 中文字幕日本一区二区| 国产精品视频色| 视频欧美精品| 亚洲最大av网站| 成人h动漫精品一区二区器材| 成人女人免费毛片| 日韩精选在线| 亚洲 国产 欧美一区| 99久久精品费精品国产风间由美| 国产成年人在线观看| 激情久久五月| 草草久久久无码国产专区| 三级欧美韩日大片在线看| 91极品视频在线观看| 韩国成人在线视频| 国产乱国产乱老熟300部视频| bt7086福利一区国产| 丰腴饱满的极品熟妇| 国产精品视频一二三| 91精品国产闺蜜国产在线闺蜜| 亚洲国产视频一区二区| 制服.丝袜.亚洲.中文.综合懂色| 欧美亚洲日本一区| 午夜精品久久久久久久99老熟妇 | 九色精品免费永久在线| 91sp网站在线观看入口| 久久网福利资源网站| av免费不卡| 国产精品久久77777| 日韩免费一级| 农村寡妇一区二区三区| 久久久久久免费视频| 国产美女在线一区| 美女视频黄 久久| 成熟妇人a片免费看网站| 欧美激情一区二区三区蜜桃视频| 中文字幕av久久爽av| 欧美视频一区二区三区…| 国产又粗又黄又爽| 日韩精品在线私人| 国产在线高潮| 欧洲亚洲妇女av| 日韩精品一区二区三区中文在线| 欧美xxxx黑人又粗又长精品| 欧美另类视频| 亚洲无吗一区二区三区| 成人精品电影在线观看| 欧美激情 一区| 亚洲成av人片在线观看无码| 伊人久久一区二区| 亚洲精品天天看| 秋霞在线午夜| 国产综合在线观看视频| 亚洲成a人片77777在线播放| 色哟哟免费网站| 另类的小说在线视频另类成人小视频在线| 日本不卡视频一区| 亚洲精品亚洲人成人网 | 这里只有精品电影| 九色视频在线播放| 久久久亚洲精选| 日韩最新av| 五月天男人天堂| 免费在线视频一区| 特大黑人巨人吊xxxx| 亚洲综合成人在线| 国产精品视频在线观看免费| 一区二区亚洲精品国产| 日本不卡1234视频| 97在线中文字幕| 香蕉视频官网在线观看日本一区二区| 亚洲中文字幕久久精品无码喷水| 99视频精品全部免费在线| 欧美久久久久久久久久久久| 91.com在线观看| 午夜小视频在线| 国产精品一区二区三| 九一精品国产| 国产性生交xxxxx免费| 97se亚洲国产综合自在线观| 伊人国产在线观看| 日韩精品一区二区三区在线观看| 2024最新电影在线免费观看| 亚洲www在线| 66视频精品| 91网址在线观看精品| 亚洲日本一区二区| 国产精品探花视频| 久久艳片www.17c.com| 高清不卡一区| 青青青在线观看视频| 国产69精品久久久久777| 国产一级特黄视频| 亚洲精品一区二区三区影院| 日韩激情电影| 欧美色图亚洲自拍| 全部av―极品视觉盛宴亚洲| 蜜桃视频最新网址| 3d成人h动漫网站入口| 羞羞网站在线看| 激情一区二区三区| 天堂av在线一区| 东京热无码av男人的天堂| 制服丝袜激情欧洲亚洲| av软件在线观看| 官网99热精品| 免费一级欧美片在线播放| 中文字幕免费视频| 欧美日韩国产首页| 91中文在线| 久久精品美女| 欧美bbbbb| 青青草手机视频在线观看| 亚洲成色999久久网站| 超碰aⅴ人人做人人爽欧美| 日韩av一区二区三区在线| 久久99精品国产.久久久久| 青娱乐国产在线视频| 精品视频偷偷看在线观看| 玖玖精品在线| 欧美人成在线观看| 久久精品夜色噜噜亚洲aⅴ| 92久久精品一区二区| 久久久久久久久久久网站| 奇米色欧美一区二区三区| 特级黄色片视频| 激情av一区二区| 欧美三级电影一区二区三区| 成人自拍视频网站| 水蜜桃久久夜色精品一区的特点 | 你懂的一区二区| 亚洲第一页av| 欧美一级二级三级蜜桃| 另类图片综合电影| 欧美黄色免费网址| 国产欧美精品区一区二区三区| www.久久综合| 国产福利精品视频| 欧美精品不卡| 一级二级黄色片| 亚洲韩国日本中文字幕| 久久久久黄色| 欧美a在线视频| 亚洲精选一二三| 成人不用播放器| 国产日韩在线一区二区三区|