国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

Go中看似簡單的WaitGroup源碼設計,竟然暗含這么多知識?

共 14136字,需瀏覽 29分鐘

 ·

2021-04-06 19:40

Go語言提供的協(xié)程goroutine可以讓我們很容易地寫出多線程程序,但是,如何讓這些并發(fā)執(zhí)行的goroutine得到有效地控制,這是我們需要探討的問題。正如小菜刀在《Golang并發(fā)控制簡述》中所述,Go標準庫為我們提供的同步原語中,鎖與原子操作注重控制goroutine之間的數(shù)據(jù)安全,WaitGroup、channel與Context控制的是它們的并發(fā)行為。關(guān)于、原子操作、channel 的實現(xiàn)原理小菜刀均有詳細地解析過。因此本文,我們將重點放在WaitGroup上。


初識WaitGroup


WaitGroup是sync包下的內(nèi)容,用于控制協(xié)程間的同步。WaitGroup使用場景同名字的含義一樣,當我們需要等待一組協(xié)程都執(zhí)行完成以后,才能做后續(xù)的處理時,就可以考慮使用。

 1func main() {
2    var wg sync.WaitGroup
3
4    wg.Add(2//worker number 2
5
6    go func() {
7        // worker 1 do something
8        fmt.Println("goroutine 1 done!")
9        wg.Done()
10    }()
11
12    go func() {
13        // worker 2 do something
14        fmt.Println("goroutine 2 done!")
15        wg.Done()
16    }()
17
18    wg.Wait() // wait all waiter done
19    fmt.Println("all work done!")
20}
21
22// output
23goroutine 2 done!
24goroutine 1 done!
25all work done!

可以看到WaitGroup的使用非常簡單,它提供了三個方法。雖然goroutine之間并不存在類似于父子關(guān)系,但是為了方便理解,本文會將調(diào)用Wait函數(shù)的goroutine稱為主goroutine,調(diào)用Done函數(shù)的goroutine稱呼為子goroutine。

1func (wg *WaitGroup) Add(delta int)  // 增加WaitGroup中的子goroutine計數(shù)值
2func (wg *WaitGroup) Done()          // 當子goroutine任務完成,將計數(shù)值減1
3func (wg *WaitGroup) Wait()          // 阻塞調(diào)用此方法的goroutine,直到計數(shù)值為0
4

那么它是如何實現(xiàn)的呢?在源碼src/sync/waitgroup.go中,我們可以看到它的核心源碼只有100行不到,十分地精練,非常值得學習。


前置知識


代碼少,不代表就實現(xiàn)簡單,易于理解。相反,如果讀者沒有下述中的前置知識,想要真正理解WaitGroup的實現(xiàn)是會比較費力的。在解析源碼之前,我們先過一遍這些知識(如果你都已經(jīng)掌握,那就可以直接跳到后文的源碼解析部分)。

信號量

在學習操作系統(tǒng)時,我們知道信號量是一種保護共享資源的機制,用于解決多線程同步問題。信號量s是具有非負整數(shù)值的全局變量,只能由兩種特殊的操作來處理,這兩種操作稱為PV。

  • P(s):如果s是非零的,那么Ps減1,并且立即返回。如果s為零,那么就掛起這個線程,直到s變?yōu)榉橇悖鹊搅硪粋€執(zhí)行V(s)操作的線程喚醒該線程。在喚醒之后,P操作將s減1,并將控制返回給調(diào)用者。

  • V(s)V操作將s加1。如果有任何線程阻塞在P操作等待s變?yōu)榉橇?,那?/span>V操作會喚醒這些線程中的一個,然后該線程將s減1,完成它的P操作。

在Go的底層信號量函數(shù)中

  • runtime_Semacquire(s *uint32) 函數(shù)會阻塞goroutine直到信號量s的值大于0,然后原子性地減這個值,即P操作。

  • runtime_Semrelease(s *uint32, lifo bool, skipframes int) 函數(shù)原子性增加信號量的值,然后通知被runtime_Semacquire阻塞的goroutine,即V操作。

這兩個信號量函數(shù)不止在WaitGroup中會用上,在《Go精妙的互斥鎖設計》一文中,我們發(fā)現(xiàn)Go在設計互斥鎖的時候也少不了信號量的參與。

內(nèi)存對齊

對于以下的結(jié)構(gòu)體,你能回答出它占用的內(nèi)存是多少嗎

 1type Ins struct {
2    x bool  // 1個字節(jié)
3    y int32 // 4個字節(jié)
4    z byte  // 1個字節(jié)
5}
6
7func main() {
8    ins := Ins{}
9    fmt.Printf("ins size: %d, align: %d\n", unsafe.Sizeof(ins), unsafe.Alignof(ins))
10}
11
12//output
13ins size: 12, align: 4

按照結(jié)構(gòu)體中字段的大小而言,ins對象占用內(nèi)存應該是 1+4+1=6 個字節(jié),但是實際上確實12個字節(jié),這就是內(nèi)存對齊所致。從《CPU緩存體系對Go程序的影響》一文中,我們知道CPU的內(nèi)存讀取并不是一個字節(jié)一個字節(jié)地讀取的,而是一塊一塊的。因此,在類型的值在內(nèi)存中對齊的情況下,計算機的加載或者寫入會很高效。

在聚合類型(結(jié)構(gòu)體或數(shù)組)的內(nèi)存所占長度或許會比它元素所占內(nèi)存之和更大。編譯器會添加未使用的內(nèi)存地址用于填充內(nèi)存空隙,以確保連續(xù)的成員或元素相當于結(jié)構(gòu)體或數(shù)組的起始地址是對齊的。

因此,在我們設計結(jié)構(gòu)體時,當結(jié)構(gòu)體成員的類型不同時,將相同類型的成員定義在相鄰位置可以更節(jié)省內(nèi)存空間。

原子操作CAS

CAS是原子操作的一種,可用于在多線程編程中實現(xiàn)不被打斷的數(shù)據(jù)交換操作,從而避免多線程同時改寫某一數(shù)據(jù)時由于執(zhí)行順序不確定性以及中斷的不可預知性產(chǎn)生的數(shù)據(jù)不一致問題。該操作通過將內(nèi)存中的值與指定數(shù)據(jù)進行比較,當數(shù)值一樣時將內(nèi)存中的數(shù)據(jù)替換為新的值。關(guān)于Go中原子操作的底層實現(xiàn),小菜刀在《同步原語的基石》一文中有詳細介紹。

移位運算 >> 與 <<

在之前關(guān)于鎖的文章《Go精妙的互斥鎖設計》與《Go更細粒度的讀寫鎖設計中》,我們能看到大量的位運算操作。靈活的位運算,能讓一個普通的數(shù)字變化出豐富的含義,這里僅介紹下文中會用到的移位運算。

對于左移位運算 <<,按二進制形式將所有的數(shù)字向左移動對應的位數(shù),高位舍棄,低位的空位補零。在數(shù)字沒有溢出的前提下,左移一位相當于乘以2的1次方,左移n位就相當于乘以2的n次方。

對于右移位運算 >>,按二進制形式把所有的數(shù)字向右移動對應位數(shù),低位移出,高位的空位補符號位。右移一位相當于除2,右移n位相當于除以2的n次方。這里是取商,余數(shù)就不要了。

移位運算也可以有很巧妙的操作,后文中我們會看到移位運算的高級運用。

unsafa.Pointer指針與uintptr

Go中的指針可以分為三類:1.普通類型指針*T,例如*int;2. unsafe.Pointer指針;3. uintptr。

  • *T:普通的指針類型,用于傳遞對象地址,不能進行指針計算。

  • unsafe.Pointer指針:通用型指針,任何一個普通類型的指針*T都可以轉(zhuǎn)換為unsafe.Pointer指針,而且unsafe.Pointer類型的指針還可以轉(zhuǎn)換回普通指針,并且它可以不用和原來的指針類型*T相同。但是它不能進行指針計算,不能讀取內(nèi)存中的值(必須通過轉(zhuǎn)換為某一具體類型的普通指針才行)。

  • uintptr:準確來講,uintptr并不是指針,它是一個大小并不明確的無符號整型。unsafe.Pointer類型可以與uinptr相互轉(zhuǎn)換,由于uinptr類型保存了指針所指向地址的數(shù)值,因此可以通過該數(shù)值進行指針運算。GC時,不會將uintptr當做指針,uintptr類型目標會被回收。

unsafe.Pointer 是橋梁,可以讓任意類型的普通指針實現(xiàn)相互轉(zhuǎn)換,也可以將任意類型的指針轉(zhuǎn)換為 uintptr 進行指針運算。但是,unsafe.Pointer和任意類型指針的轉(zhuǎn)換可以讓我們將任意值寫入內(nèi)存中,這會破壞Go原有的類型系統(tǒng),同時由于不是所有的數(shù)值都是合法的內(nèi)存地址,從uintptr到unsafe.Pointer的轉(zhuǎn)換同樣會破壞類型系統(tǒng)。因此,既然Go將該包定義為unsafe,那就不應該隨意使用。


源碼解析


本文基于Go源碼1.15.7版本

結(jié)構(gòu)體

sync.WaitGroup的結(jié)構(gòu)體定義如下,它包括了一個 noCopy 的輔助字段,和一個具有復合意義的state1字段。

 1type WaitGroup struct {
2    noCopy noCopy
3
4    // 64-bit value: high 32 bits are counter, low 32 bits are waiter count.
5    // 64-bit atomic operations require 64-bit alignment, but 32-bit
6    // compilers do not ensure it. So we allocate 12 bytes and then use
7    // the aligned 8 bytes in them as state, and the other 4 as storage
8    // for the sema.
9    state1 [3]uint32
10}
11
12// state returns pointers to the state and sema fields stored within wg.state1.
13func (wg *WaitGroup) state() (statep *uint64, semap *uint32) {
14  // 64位編譯器地址能被8整除,由此可判斷是否為64位對齊
15    if uintptr(unsafe.Pointer(&wg.state1))%8 == 0 {
16        return (*uint64)(unsafe.Pointer(&wg.state1)), &wg.state1[2]
17    } else {
18        return (*uint64)(unsafe.Pointer(&wg.state1[1])), &wg.state1[0]
19    }
20}

其中,noCopy字段是空結(jié)構(gòu)體,它并不會占用內(nèi)存,編譯器也不會對其進行字節(jié)填充。它主要是為了通過go vet工具來做靜態(tài)編譯檢查,防止開發(fā)者在使用WaitGroup過程中對其進行了復制,從而導致的安全隱患。關(guān)于這部分內(nèi)容,可以閱讀《no copy機制》詳細了解。

state1字段是一個長度為3的uint32數(shù)組。它用于表示三部分內(nèi)容:1. 通過Add()設置的子goroutine的計數(shù)值counter;2. 通過Wait()陷入阻塞的waiter數(shù);3. 信號量semap。

由于后續(xù)是對 uint64 類型的statep進行操作,而64位整數(shù)的原子操作需要64位對齊,32位的編譯器并不能保證這一點。因此,在64位與32位的環(huán)境下,state1字段的組成含義是不相同的。

需要注意的是,當我們初始化一個WaitGroup對象時,其counter值、waiter值、semap值均為0。

Add函數(shù)

Add()函數(shù)的入?yún)⑹且粋€整型,它可正可負,是對counter數(shù)值的更改。如果counter數(shù)值變?yōu)?,那么所有阻塞在Wait()函數(shù)的waiter將會被喚醒;如果counter數(shù)值為負值,將引起panic。

我們將競態(tài)檢測部分的代碼去掉,Add()函數(shù)的實現(xiàn)源碼如下

 1func (wg *WaitGroup) Add(delta int) {
2  // 獲取包含counter與waiter的復合狀態(tài)statep,表示信號量值的semap
3    statep, semap := wg.state()
4    state := atomic.AddUint64(statep, uint64(delta)<<32)
5    v := int32(state >> 32)
6    w := uint32(state)
7
8    if v < 0 {
9        panic("sync: negative WaitGroup counter")
10    }
11
12    if w != 0 && delta > 0 && v == int32(delta) {
13        panic("sync: WaitGroup misuse: Add called concurrently with Wait")
14    }
15
16    if v > 0 || w == 0 {
17        return
18    }
19
20    if *statep != state {
21        panic("sync: WaitGroup misuse: Add called concurrently with Wait")
22    }
23
24  // 如果執(zhí)行到這,一定是 counter=0,waiter>0
25  // 能執(zhí)行到這,一定是執(zhí)行了Add(-x)的goroutine
26  // 它的執(zhí)行,代表所有子goroutine已經(jīng)完成了任務
27  // 因此,我們需要將復合狀態(tài)全部歸0,并釋放掉waiter個數(shù)的信號量
28    *statep = 0
29    for ; w != 0; w-- {
30    // 釋放信號量,執(zhí)行一次就將喚醒一個阻塞的waiter
31        runtime_Semrelease(semap, false0)
32    }
33}

代碼非常精簡,我們接下來對關(guān)鍵部分進行剖析。

1     state := atomic.AddUint64(statep, uint64(delta)<<32)  // 新增counter數(shù)值delta
2    v := int32(state >> 32)   // 獲取counter值
3    w := uint32(state)        // 獲取waiter值

此時的statep是一個uint64數(shù)值,如果此時statep中包含的counter數(shù)為2,waiter為1,輸入delta為1,那么這三行代碼的邏輯過程如下圖所示。

在得到當前counter數(shù)v與waiter數(shù)w后,會對它們的值進行判斷,分幾種情況。

 1    // 情況1:這是很低級的錯誤,counter值不能為負
2  if v < 0 {
3        panic("sync: negative WaitGroup counter")
4    }
5
6  // 情況2:misuse引起panic
7  // 因為wg其實是可以用復用的,但是下一次復用的基礎(chǔ)是需要將所有的狀態(tài)重置為0才可以
8    if w != 0 && delta > 0 && v == int32(delta) {
9        panic("sync: WaitGroup misuse: Add called concurrently with Wait")
10    }
11
12  // 情況3:本次Add操作只負責增加counter值,直接返回即可。
13  // 如果此時counter值大于0,喚醒的操作留給之后的Add調(diào)用者(執(zhí)行Add(negative int))
14  // 如果waiter值為0,代表此時還沒有阻塞的waiter
15    if v > 0 || w == 0 {
16        return
17    }
18
19  // 情況4: misuse引起的panic
20    if *statep != state {
21        panic("sync: WaitGroup misuse: Add called concurrently with Wait")
22    }

關(guān)于 misuse 和 reused 引發(fā) panic 的情況,如果沒有示例錯誤代碼,其實是比較難解釋的。值得高興的是,在Go源碼中給出了錯誤使用示范,這些例子位于src/sync/waitgroup_test.go文件下,想深入了解的讀者可以去看以下三個測試函數(shù)中的示例。

1func TestWaitGroupMisuse(t *testing.T)
2func TestWaitGroupMisuse2(t *testing.T)
3func TestWaitGroupMisuse3(t *testing.T)
4

Done函數(shù)

Done()函數(shù)比較簡單,就是調(diào)用Add(-1)。在實際使用時,當子goroutine任務完成之后,就應該調(diào)用Done()函數(shù)。

1func (wg *WaitGroup) Done() {
2    wg.Add(-1)
3}
Wait函數(shù)

如果WaitGroup中的counter值大于0,那么執(zhí)行Wait()函數(shù)的主goroutine會將waiter值加1,并阻塞等待該值為0,才能繼續(xù)執(zhí)行后續(xù)代碼。

我們將競態(tài)檢測部分的代碼去掉,Wait()函數(shù)的實現(xiàn)源碼如下

 1func (wg *WaitGroup) Wait() {
2    statep, semap := wg.state()
3    for {
4        state := atomic.LoadUint64(statep) // 原子讀取復合狀態(tài)statep
5        v := int32(state >> 32)            // 獲取counter值
6        w := uint32(state)                 // 獲取waiter值
7    // 如果此時v==0,證明已經(jīng)沒有待執(zhí)行任務的子goroutine,直接退出即可。
8        if v == 0 {
9            return
10        }
11        // 如果在執(zhí)行CAS原子操作和讀取復合狀態(tài)之間,沒有其他goroutine更改了復合狀態(tài)
12    // 那么就將waiter值+1,否則:進入下一輪循環(huán),重新讀取復合狀態(tài)
13        if atomic.CompareAndSwapUint64(statep, state, state+1) {
14      // 對waiter值累加成功后
15      // 等待Add函數(shù)中調(diào)用 runtime_Semrelease 喚醒自己
16            runtime_Semacquire(semap)
17      // reused 引發(fā)panic
18      // 在當前goroutine被喚醒時,由于喚醒自己的goroutine通過調(diào)用Add方法時
19      // 已經(jīng)通過 *statep = 0 語句做了重置操作
20      // 此時的復合狀態(tài)位不為0,就是因為還未等Waiter執(zhí)行完Wait,WaitGroup就已經(jīng)發(fā)生了復用
21            if *statep != 0 {
22                panic("sync: WaitGroup is reused before previous Wait has returned")
23            }
24            return
25        }
26    }
27}


總結(jié)


要看懂WaitGroup的源碼實現(xiàn),我們需要有一些前置知識,例如信號量、內(nèi)存對齊、原子操作、移位運算和指針轉(zhuǎn)換等。

但其實WaitGroup的實現(xiàn)思路還是蠻簡單的,通過結(jié)構(gòu)體字段state1維護了兩個計數(shù)器和一個信號量,計數(shù)器分別是通過Add()添加的子goroutine的計數(shù)值counter,通過Wait()陷入阻塞的waiter數(shù),信號量用于阻塞與喚醒Waiter。當執(zhí)行Add(positive n)時,counter +=n,表明新增n個子goroutine執(zhí)行任務。每個子goroutine完成任務之后,需要調(diào)用Done()函數(shù)將counter值減1,當最后一個子goroutine完成時,counter值會是0,此時就需要喚醒阻塞在Wait()調(diào)用中的Waiter。

但是,在使用WaitGroup時,有幾點需要注意

  • 通過Add()函數(shù)添加的counter數(shù)一定要與后續(xù)通過Done()減去的數(shù)值一致。如果前者大,那么阻塞在Wait()調(diào)用處的goroutine將永遠得不到喚醒;如果后者大,將會引發(fā)panic。

  • Add()的增量函數(shù)應該最先得到執(zhí)行。

  • 不要對WaitGroup對象進行復制使用。

  • 如果要復用WaitGroup,則必須在所有先前的Wait()調(diào)用返回之后再進行新的Add()調(diào)用。


推薦閱讀


福利

我為大家整理了一份從入門到進階的Go學習資料禮包,包含學習建議:入門看什么,進階看什么。關(guān)注公眾號 「polarisxu」,回復 ebook 獲??;還可以回復「進群」,和數(shù)萬 Gopher 交流學習。

瀏覽 45
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 国产在线拍偷自揄拍无码一区二区| 日韩国产AV| 奇米影视狠狠干| 韩国无码高清视频| 人人草人人看人人摸| 爱搞视频在线观看| 人妻大屁股-91Porn| 视色视频在线观看18| 一本久久综合亚洲鲁鲁五月天| 国产精品色在线回看| 人妻日韩| 黄片免费看视频| 国产黄色视频免费在线观看| 中文字幕无码一区二区三区一本久 | 精品人妻一区二区| 日本成人三级片| 大地影视中文第三页最新在线观看| 一区二区三区国产精品| 大奶一区二区| 国产精品视频播放| 色哟哟国产精品| 欧美色图888| 真实国产乱子伦毛片| 波多野结衣vs黑人巨大| 免费日比视频| 精品视频网| 欧美日韩无码| 国产天堂| 一级A级毛片| 日韩七区| 嫩草视频| 国产精品久久毛片| 中文字幕免费在线观看| 欧美日韩第一区| 欧美福利电影| 小佟丽娅大战91哥| 成人午夜免费视频| 精品一区二区三区四区视频| 日韩无码影视| 欧美三级网址| 久久午夜无码人妻精品蜜桃冫| 91干干| 久久成人导航| 亚洲秘无码一区二区三区胖子| 伊人影院在线免费观看| 国产精品无码av| 影音先锋资源| 久久国产精品一区二区三区| 九九九色视频| 亚洲图片激情乱伦小说| 国产无码网站| 日本不卡一区二区三区| 一级A黄片| 日啪| 人妻无码一区二区三区| 黄色一级大片在线免费看国产| 东方AV免费在线观看| 北条麻妃无码精品AV怎么看| 日本黄色电影网站| 日韩人妻精品无码久久| 无码视频网| 亚洲精品一级二级三级| 五月天高清无码| www.五月天.con| 日韩porn| 91在线无码精品秘软件| 黄色片免费视频网站| 91在线视频播放| 欧美成人猛片AAAAAAA| 99久| 午夜福利免费| 亚洲在线高清| 人人妻人人要| 91骚| 亚洲无码AV在线观看| 亚洲婷婷在线视频| 在线观看免费a片| 亚洲综合成人在线| 91视频综合网| 黑人干亚洲人| 国产A片录制现场妹子都很多| 国产欧美日韩| 亚洲AV免费在线观看| 黄色小视频免费看| av黄色在线观看| 精品99视频| 国产熟妇婬乱A片免费看牛牛| 国产熟妇毛多久久久久一区 | AV成人无码| 大香蕉色婷婷| 亚洲精品日韩综合观看成人91| 91一区二区在线观看| 麻豆视频在线免费观看| 婷婷五月电影| 免费AV观看| 少妇高潮av久久久久久| 欧美爱| 免费一级婬片AAA片毛片A级| 按摩忍不住BD中文字幕| 很很日| 最新精品视频| 国产牛牛在线| 五月六月丁香激情视频| 逼特逼视频网站| 国产91一区在线精品| 秋霞91| 久久久久久无码日韩欧美电影| 午夜撸一撸| 狠狠干高清成人二区三区| 成人大战香蕉最新视频| 免费成人黄视频| 不卡无码中文字幕一区| 成人色播播| 国产一级a毛一级a做免费的视频l 精品国产免费观看久久久_久久天天 | 夜夜骑夜夜撸| 国产亚洲欧美视频| 激情五月伊人| 久久大鸡巴| 久草性爱| 亚洲高清无码视频在线| 色五月av| 神马午夜精品| 国产一级a毛一级a做免费高清视频| 午夜成人小电影| 成人免费在线观看| 人人爽人人澡| 国产精品扒开腿做爽爽爽A片唱戏| 男人的天堂视频| 亚洲一区在线视频| 久久黄色片| 影音先锋成人电影| 久久嫩草精品久久久久精| 2019中文字幕在线| 日韩一级爱爱| 91成人免费在线观看| 久久青青草在线视频| 超碰人人爱人人操| 69欧美视频| 麻豆AV在线播放| 99热精品国产| A视频免费观看| 久久国产黄色视频| 国产区av| 免费看一区二区三区A片| 亚洲无码视频免费观看| 三级片AAA成人免费| 性做久久久久久久久| 免费人成视频在线| 久久黄色网络| 四川少扫搡BBw搡BBBB| 亚洲无码在线免费观看视频| 成人在线观看网站| 亚洲精品无码在线观看| 日韩精品一区二区三区四在线播放| 亚洲AV无码一区二区三区少妇| WW免费视频| 亚洲中文AV在线| 欧美色爽| 东方av在线免费观看| 波多野结衣日韩| 少妇bbw搡bbbb搡bbbb| 自拍偷拍视频网站| 中文字幕日本| 2025精品精品视频| 国产三级高清无码| 中文字幕一区二区三区人妻电影| 波多野结衣AV在线观看| 尿在小sao货里面好不好| 亚洲综合精品| 亚洲图片一区| 欧美69视频| 99精品视频免费观看| 99er在线观看视频| 先锋影音av资源站| 欧美黑人操逼| 欧美另类视频| 成人黄色网| 中文字幕在线观看一区二区三区| 国产凹凸视频在线观看| 亚洲制服中文字幕| 五月丁香婷婷激情| 91好爽| 免费无码国产在线观看快色| 波多野结衣网站| 国产一级二级三级视频| 97免费在线观看视频| 婷婷五月天影视| 农村老太HD肉HD| 欧美黄色片在线观看| 东京热综合网| 国产亚洲视频在线观看视频| 91视频免费在线看| www.五月天.con| 伊人69| 亚洲视频中文字幕| 99re这里只有| 天堂8在线19| 成人做爰100片免费着| 国产女人高潮毛片| 成人黄色视频免费| 西西特级无码444www| 国产精品美女| 激情网站免费| 国产精品成人在线视频| 无码在线观看免费视频| 9I免费看片黄| 亚洲成人自拍| 国产成人精品亚洲男人的天堂 | 四季AV一区二区凹凸懂色桃花| 高圆圆一区二区三区| 第一页在线观看| 午夜福利剧场| 77777色婷婷| 国产又爽又黄视频| 国产日B| 欧美黄页| 国产精品观看| 在线观看国产| 国产精品色呦呦| 大香蕉久久伊人| 9l农村站街老熟女| 人人妻人人| 久久久桃色| av在线小说| 久久久高清无码| 色片在线| 伊人在线视频| 免费观看成人片| 国产免费一级特黄A片| av在线资源观看| 一区在线播放| 欧美在线成人网| 国产系列精品AV| 香蕉AV777XXX色综合一区| 亚洲精品大片| 日本成人中文字幕在线观看| 亚洲黄色小电影| 久久成人三级片| 久久久亚洲| 日本人妻中出| 久久久123| 深夜福利av| 天天干天天干天天日| 国产精品久久久一区二区三区 | 日韩色图在线观看| 蜜桃视频在线观看视频| 天天干B| 国产熟女一区二区三区五月婷| 五月天无码免费视频| 五月天无码在线| 亚洲综合中文| 色老板在线精品免费观看| 久久人妻精品| 欧美在线色图| 国产美女自拍| 青娱乐无码视频| 久久蝌蚪窝| 黄网在线看| 日韩成人无码特集| www免费视频在线观看播放| www.国产在线观看| 久久人妻无码中文字幕系列| 日本一级特级毛片视频| 亚洲成人AV在线播放| 亚洲无码在线免费观看| 小小拗女BBw搡BBBB搡| 蜜桃AV无码一区二区三区| 日本黄色三级视频| av大片在线观看| 免费版成人久久幺| 骚逼综合| 免费成人AV| 91涩| 色哟哟国产精品| 丝袜制服中文字幕无码专区| 无码一区二区黑人猛烈视频网站 | www亚洲| 综合网欧美| 先锋资源av| 强开小嫩苞毛片一二三区| 免费在线观看无码视频| 日韩黄色小说| 中国极品少妇XXX| 久久6精品| 麻豆精品久久久久久久99蜜桃| 黄色电影一区二区三区| 亚欧洲精品在线视频| 亚州毛片| 亚洲无码手机在线| 中文字幕人妻系列| 久久在线视频| 久久精品婷婷| 国产一级a毛一级a做免费图片 | 奇米影视狠狠干| 亚洲人成电影| 琪琪色五月天| 五月婷婷六月天| 日韩肏屄视频在线观看| 亚洲男女免费视频| 国产无码高潮在线| 久草三级片| 三上悠亚无码破解69XXX| 九九成人| 你懂的在线免费观看| 欧美一级在线视频| 伊人春色网| 一区二区三区四区五区| www.水蜜桃| 丰满人妻一区二区三区精品高清| 北条麻妃在线不卡| 五月婷婷六月丁香| 九一国产在线| 国产黃色AAA片| 日韩免费在线观看| 自拍偷拍AV| 蜜挑视频一区二区三区| 中文字幕免费在线观看视频| 成人A片免费视频| www.91av| 99免费热视频在线| 免费看无码一级A片在线播放| 欧美亚洲小说| 91乱子伦国产乱| 欧美三级长视频| 最近最经典中文MV字幕| 俺去也视频| 黄色福利网| 欧美成人激情视频| 人人操人人爽人人爱| 女同久久另类99精品国产91| 伊人免费| 亚洲无码中| 亚洲AV无码成人精品涩涩麻豆| 120分钟婬片免费看| 黄色大片免费在线观看| 猫咪视频大全视频| 欧美性区| 国产乱伦免费| 国产精品人妻无码久久久郑州天气网 | 国产多人搡BBBB槡BBBB| 影音先锋一区| 97人妻人人澡人人爽人人| 伊人大香蕉综合| 欧美不卡在线观看| 久久五月天婷婷| 午夜精品18码视频国产17c| 永久久久久久久| 国产自偷自拍| 亚洲五月丁香婷婷| 91免费网站| 国产欧美综合一区二区| 久操视频网| 樱桃Av| 麻豆视频一区二区| 日韩欧美日韩| 一级特黄AAAA片| 午夜H片| 日韩AV在线免费| 国产在线久久久| 在线亚洲小视频| 不卡一二三区| www.99av| 天天精品无码| 久久精品视| 日韩一区二区三免费高清在线观看| 亚洲三级在线视频| 欧美洲成人网站| 初尝人妻滑进去了莹莹视频| www.国产豆花精品区| 一区二区三区四区五区无码| 露脸偷拍AV2025| 乱视频| 国产亚洲视频完整在线观看| 中文在线免费看视频| 初学影院WWWBD英语完整版在线观看 | 日韩欧美性爱视频| 99er热精品视频| 最新日韩中文字幕| 日逼电影网| 人妖和人妖互交性XXXX视频| 国产成人A| 久久99视频免费观看| 欧美黑吊大战白妞| 揉BBB搡BBB搡BBB| 五月天无码| 操BBB操BBB| 一本大道东京热av无码| 精品无码视频在线| 插菊花综合| 激情五月婷婷色| 亚洲精品天堂无码AV片| 91视频网站在线| 黄网在线观看视频| 亚洲日逼视频| 国产欧美精品一区二区三区| 午夜三级福利| 在线免费观看成人网站| 无码aa| 国产成人精品一区二区三区视频 | 激情视频网| 2024AV在线| 伊人成人在线| 欧美黄色三级视频| 91国产精品视频在线| 日韩AV在线免费| 黄色网址在线观看视频| 一级片在线免费观看| 亚洲婷婷综合网| 一区二区高清无码| 色婷婷综合视频| 亚洲久久视频| 韩国三级HD久久精品| 一区二区三区四区五区六区高清无吗视频| 操人视频在线观看| 欧一美一伦一A片| 免费毛片网| 无码人妻AV一区| 日本人妻中文字幕| 伊人网av| 蜜桃av秘无码一区二区三| 欧美一级大香蕉| 囯产精品久久| 免费无码在线观看| 日日日日日干| 就爱操逼网| 91蝌蚪在线| 欧美不卡在线观看| 欲色av| 国产伦子伦一级A片在线| 久久人人做| 欧一美一婬一伦一区二区三区黑人| 欧产日产国产swag| a片在线免费观看| 撒尿BBw搡BBwBBw| 久久成人在线视频| 日韩黄色av| 国产免费一级特黄A片| 蜜挑视频一区二区三区| 尤物精品| 肏屄综合网| 日韩爱爱| 97乱伦| 国产一级黄色A片| 琪琪色在线观看| 99天堂网| 成人视频免费在线观看| 中文字幕在线免费播放| 日韩色妇| www国产亚洲精品久久网站| 精品一区国产| 91人兽| 俺也去av| 国产精品美女久久久久AV爽 | 空姐白洁| 黄色网址在线免费观看| 超碰人人爱人人操| 成人自拍视频| 日韩操B视频| 九色丨蝌蚪丨老版熟女| 精品九九| 三级无码在线| 亚洲婷婷在线视频| 操逼91小视频| 丁香五月激情五月| 九九五月天| 懂色成人视频在线观看| 超碰啪啪| 成人无码精品亚洲| 青青青青操| 狠狠干2018| 午夜福利播放| 国产91黄色| 亚洲一级黄| 成人在线免费电影| 日韩三级麻豆| 99免费视频在线观看| 黄色视频免费播放| 国产69视频在线观看| 国产精品无码专区| 欧美福利在线观看| 亚洲午夜无码精品专区| 国产在线成人| 久久另类TS人妖一区二区| 97香蕉久久夜色精品国产| 国产黄色免费| 爱爱成人视频| 国产乱╳╳AⅤ毛片| 无套免费视频欧美| 亚洲中文无码字幕| 国产精品欧美一区二区| 乱伦乱伦乱伦中文字幕| 欧美一区二区三区在线| AV中文字幕在线播放| 91久久无码一区人妻A片蜜桃| 欧美色伊人| 大香蕉性爱视频| 夜夜撸天天干| 日韩av无码中文字幕| av资源在线| 免费在线看黄色| 狠狠干狠狠艹| 日韩AV无码专区亚洲AV紧身裤| 国产乱妇无码毛片A片在线看下载| 9999国产精品| 操逼视频在线免费看| xiuxiuav| 精品国产91| 久草手机视频在线观看| 日本无码毛片| 久久中文字幕综合| 久久久一区二区三区四区| 色综合久久久无码中文字幕999 | 久久思热国产| 无码在线免费观看| 国产精品无码白浆高潮| 日韩中文字幕专区| 日韩在线中文字幕亚洲| 三级网址在线观看| 国产迷奸视频| 91x色| 中文字幕线观看| 亚洲中文在线视频| 亚洲综合天堂| 欧美国产综合| 亚洲va欧美va| 肉片无遮挡一区二区三区免费观看视频 | 日本成人性爱视频网站一区| 亚洲精品大片| 日皮视频在线| 在线播放亚洲| 欧美成人精品A片免费一区99| 婷婷五月天视频| 国产内射无码| 最新中文字幕av| 久久久久亚洲AV无码专区成人| 久久久精品黄色网址| 国产精品久久久精品| 久久精品www人人爽人人| www.AV在线| 亚洲av二区| 婷婷色综合视频二区| 国产成人精品无码免费| 无码日韩视频| 中文字幕VA| 2024av在线| 中文无码日韩| 日韩欧美激情| 久久大| 一区二区三区四区| 中文字幕永久在线视频v1.0| 波多野结衣黄色| 激情五月丁香五月| 六月婷婷中文字幕| 日欧内射| 免费的AV网站| 最新中文字幕视频| 国产啊啊啊| 91精品国自产在线观看| 亚洲69p| 亚洲AV一二三区| 中文字幕婷婷五月天| 人人操人人干人人操| yw在线观看| 国产精品A片守望| 黄色毛片一级| 日韩成人三级片| 先锋影音资源一区| 日韩一级中文字幕| 日本高清视频九区| www.麻豆网91成人久久久| 亚洲最大无码| 丁香五月六月婷婷| 精品国产女人| 色哟哟――国产精品| 在线观看无码AV| 99青草在线视频| 插逼网站| 国产av中文字幕| 九九热国产视频| 91精品在线观看视频| 亚洲在线资源| 欧一美一婬一伦一区二区三区| 老太奶性BBwBBw侧所| 中文字幕精品人妻在线| 激情一区二区三区| 欧美精品无码| 人妻精品在线| 亚洲无吗在线观看| 91丨PORN丨国产| 久久影院av| 亚州AV在线| 北条麻妃久久视频在线播放 | 久热国产精品| 国产欧美在线看| 亚洲AV成人无码一区二区三区| 亚洲午夜久久久| 444444在线观看免费高清电视剧木瓜一 | 另类老妇性BBwBBw| 91精品福利| 成年人黄色片| 欧美日韩免费一区二区三区| 日韩熟妇无码中文字慕| 日韩日韩日韩日韩| 男人天堂视频在线| 国产操逼网址| 97爱爱视频| 久久黄色A片| 久久中文字幕免费| 69天堂| 无码午夜| 欧美色图在线播放| 天天操天天干天天射| 欧美一区不卡| sese在线| 免费在线黄色视频| 先锋影音资源AV| 美女91网站色| 草久伊人| 9无码| 日本少妇高潮喷水XXXXXXX| 波多野结衣高清av久久直播免 | 久久精品视频99| 无码视频韩国| 欧美AA视频| 黄色电影一区二区| 亚洲一级性爱| 操逼视频电影| 特写毛茸茸BBwBBwBBw| 欧美精品一区二区少妇免费A片 | 成人性生交片无码免费看人| 亚洲视频欧洲视频| WWW.豆花视频精品| A一级黄色| 91视频在线观看网| 一区二区三区精品| 国产a区| 亚洲欧洲在线视频| 农村A片婬片AAA毛片| 久草综合视频| 在线看黄片| 日本少妇高潮| 日本欧美亚洲| 五月开心激情网| 中文字幕精品无码一区二区| 亚洲第一黄网| 欧洲成人在线视频| 十八禁无码网站在线观看| 国产av日韩| 日韩AV无码一区二区三区| 亚洲网站在线播放| 在线视频一区二区三区四区| 日本免费爱爱| 嫩草久久99www亚洲红桃| 欧美亚洲成人电影| 欧美成人大片| 91人妻人人澡人人爽精品| 成人性爱视频网站| 免费在线观看视频黄| 日韩十八禁网站| 亚洲无码AV网站| 亚洲精品成人一二三区| 国产不卡在线视频| 成人视频18+在线观看| 亚洲成人免费在线| 日韩激情一区| 色色色色五月| 天堂一区在线观看| 亚洲区在线| 亚洲国产精品午夜福利| 久久久精品免费| 国产视频福利在线| 91网站免费在线观看| 中文字幕一区二区三区四区五区六区 | 亚洲国产成人91精品| 青娱乐精品在线视频| 欧美成人网站免费在线观看| 亚洲欧洲无码视频| 婷婷五月中文| 亚洲网站免费观看| 91骚| 91三级电影| 性生活黄色视频| 久久黄色免费视频| 伊人久久中文字幕| 七十路の高齢熟女千代子| 超碰人人射| 撸一撸在线视频| 国产一区二区在线视频| 成人午夜免费视频| 91在线精品秘一区二区黄瓜| 亚洲无码电影在线观看| 国产黄色视频在线观看| 成人AV电影在线观看| 69午夜| 天堂无码视频在线播放| 色色色免费视频| 色婷婷狠狠操| 久久伊人电影| 三级无码在线观看| 日韩欧美中文字幕在线视频| 99性爱| 国产一级女婬乱免费看| v在线| 熟女人妻人妻HD| 日本无码中文字幕| 黄片av| 欧洲成人在线播放| 久久人妻视频| 国产欧美精品一区二区三区| 国产精品自产拍| 美女一级A片| 免费69视频看片| 日韩亚洲中文字幕| 国产熟妇毛多久久久久一区| 成人免费在线观看| 陈冠希和张柏芝mv| 国产欧美日韩在线| 国产福利视频| 日韩三级在线免费观看| 老女人操屄| 天天射天天日天天干| 午夜免费无码| 免费无码在线播放| 欧美精产国品一区二区区别| 无码国产高清| 亚洲免费观看高清完整版在线| 黄片免费在线播放| 激情AV在线| 国产无码免费视频| 五月天激情午夜福利| 亚洲人妻免费视频| 日韩在线视频二区| 黑人亚洲娇小videos∞| 97操| 91人妻人人澡人人爽人人精 | 欧美mv日韩mv国产网站| 国产精品久久久久久久免牛肉蒲| 黄色九九| 中文字幕在线播放第一页| 荫蒂添到高潮免费视频| 午夜AV福利| 亚洲高清无码一区二区三区| 久久国产性爱| 久久久999| 详情:绿帽夫妻多人运动开淫啪-91n | 在线黄色AV| 免费黄色视频网站| 老女人的逼| 91夫妻交友视频| 国产高清精品无码| 一级片网址| 日韩精品成人免费观看视频| 日韩无码性爱视频| 99精品免费| 国产十八岁在线观看| 久久久久亚洲| 米奇电影777无码| 亚洲精品色婷婷| 影音先锋av成人电影| 蜜桃AV无码一区二区三区| 欧美亚洲一区二区三区| 黄色小视频在线观看| 人人做人人爱人人做人人乐的意思| 青青操国产乱伦| 亚洲无码你懂的| 亚洲AV图片| 日韩无码视频网站| www.蜜桃视频| 91精品国产综合久久久蜜臀酒店| 巨い巨乳の少妇あジed2k | 91大长腿美女花外围在线观看| 久久午夜成人电影| 91色在线视频| 欧美日韩不卡视频| 五月天婷婷基地| 成人无码一区| 成人社区视频| 精品成人网| 国产成人无码精品| 日韩免费观看视频| 91牛| 高潮喷水AⅤ| 中国12一13毛片| 亚洲无码视频看看| 五月天婷婷基地| www.麻豆网91成人久久久| 日韩99在线观看| 91白丝喷水自慰网站| 亚洲天堂大香蕉| 色拍拍视频| 黄色视频网站免费在线观看| 黄片网站免费观看| 国产亚洲99久久精品| 欧美日韩综合网| 2021国产视频| 北条麻妃无码精品AV| 123操逼| 北条麻妃一区二区三区在线| 91嫖妓站街埯店老熟女| 操逼操逼视频| 香蕉伊人| 狠狠干| 欧美性爱在线网站| 色播AV| 中文字幕11页| 日本无码一区二区| 日韩一区二区免费看| 亚洲成人网站免费观看| 麻豆国产91在线播放| 国产传媒在线观看| 中文无码久久| 中文无码AV在线| 国产做受91一片二片老头| 一级黄色视频在线观看| 大香蕉电影网| 亚洲中文无码在线观看| 亚洲AV无码成人精品区在线欢看| 99这里有精品视频| 日韩视频在线免费观看| 在线看V片| 成人一区视频| 国产足交| 国内精品国产成人国产三级| 大香蕉伊人影视| 亚洲天堂婷婷| 中文字幕无码视频在线观看| 一级片A片| 逼特逼视频网站| 暖暖av| 欧美黄色毛片| 成人久久久| 粉嫩小泬BBBB免费看| 又黄又色的视频| www.激情| 无码人妻一区二区三区免费九色| 黄色美女毛片| 嫩小槡BBBB槡BBBB槡免费-百度| 欧美日本国产| 黄色一区在线| 欧美AAA| 日韩乱伦AV| 亚洲高清无码视频在线观看| 中文字幕在线播放AV| a级片在线观看| 免费一级无码成人片| 国产AV福利| 天堂中文8资源在线8| 久久久久久久免费| 国产成人一区二区三区| 操一操干一干| 激情爱爱网站| 嫩小槡BBBB槡BBBB槡漫画| 超碰199| 久久AV电影| 亚洲电影无码| 中文字幕视频一区| 精品爆乳| 国产第一页在线播放| 99香蕉视频| 国产精品操逼网站| 超碰免费91| 五月综合激情| 另类视频区| 一级欧美黑人大战白妞| 熟妇自拍| 久久久久久一| 美日韩精品| 2014天堂网| A片地址| 熟女老阿V8888AV| 大香蕉久久爱| 豆花无码视频一区二区| 久久综合操| 亚洲一区二区av| 亚洲北条麻妃一级A片| 午夜性爱视频| 国产精品A片守望| 麻豆精品传媒国产剧的特点| 韩国一区二区三区| 日韩精品久久久久久久| 五月亚洲六月婷婷| 影音先锋国产在线| 青青草大香蕉| 女人久久久久| 波多野结衣亚洲视频| 在线播放你懂的| 国产成人黄色片| 成人黄色视频免费| 在线一区| 国产18禁网站| 精品国产一区二区三区久久久蜜月 | 国产搡BBB爽爽爽视频| 成人欧美在线观看| 超碰亚洲| 老熟女网站| 亚洲第一黄网| www一个人免费观看视频www| 东京热久久综合| 操逼影视| 尤物视频网站在线观看|