成人性生交大片免费看视频r_亚洲综合极品香蕉久久网_在线视频免费观看一区_亚洲精品亚洲人成人网在线播放_国产精品毛片av_久久久久国产精品www_亚洲国产一区二区三区在线播_日韩一区二区三区四区区区_亚洲精品国产无套在线观_国产免费www

主頁 > 知識(shí)庫 > golang 并發(fā)安全Map以及分段鎖的實(shí)現(xiàn)方法

golang 并發(fā)安全Map以及分段鎖的實(shí)現(xiàn)方法

熱門標(biāo)簽:高德地圖標(biāo)注口訣 學(xué)海導(dǎo)航地圖標(biāo)注 廣州呼叫中心外呼系統(tǒng) 江西轉(zhuǎn)化率高的羿智云外呼系統(tǒng) 西部云谷一期地圖標(biāo)注 浙江高速公路地圖標(biāo)注 南通如皋申請(qǐng)開通400電話 地圖標(biāo)注的汽車標(biāo) 中國地圖標(biāo)注省會(huì)高清

涉及概念

  1. 并發(fā)安全Map
  2. 分段鎖
  3. sync.Map
  4. CAS ( Compare And Swap )
  5. 雙檢查

分?jǐn)噫i

type SimpleCache struct {
  mu  sync.RWMutex
  items map[interface{}]*simpleItem
}

在日常開發(fā)中, 上述這種數(shù)據(jù)結(jié)構(gòu)肯定不少見,因?yàn)間olang的原生map是非并發(fā)安全的,所以為了保證map的并發(fā)安全,最簡單的方式就是給map加鎖。

之前使用過兩個(gè)本地內(nèi)存緩存的開源庫, gcache, cache2go,其中存儲(chǔ)緩存對(duì)象的結(jié)構(gòu)都是這樣,對(duì)于輕量級(jí)的緩存庫,為了設(shè)計(jì)簡潔(包含清理過期對(duì)象等 ) 再加上當(dāng)需要緩存大量數(shù)據(jù)時(shí)有redis,memcache等明星項(xiàng)目解決。 但是如果拋開這些因素遇到真正數(shù)量巨大的數(shù)據(jù)量時(shí),直接對(duì)一個(gè)map加鎖,當(dāng)map中的值越來越多,訪問map的請(qǐng)求越來越多,大家都競爭這一把鎖顯得并發(fā)訪問控制變重。 在go1.9引入sync.Map 之前,比較流行的做法就是使用分段鎖,顧名思義就是將鎖分段,將鎖的粒度變小,將存儲(chǔ)的對(duì)象分散到各個(gè)分片中,每個(gè)分片由一把鎖控制,這樣使得當(dāng)需要對(duì)在A分片上的數(shù)據(jù)進(jìn)行讀寫時(shí)不會(huì)影響B(tài)分片的讀寫。

分段鎖的實(shí)現(xiàn)

// Map 分片
type ConcurrentMap []*ConcurrentMapShared

// 每一個(gè)Map 是一個(gè)加鎖的并發(fā)安全Map
type ConcurrentMapShared struct {
  items map[string]interface{}
  sync.RWMutex  // 各個(gè)分片Map各自的鎖
}

主流的分段鎖,即通過hash取模的方式找到當(dāng)前訪問的key處于哪一個(gè)分片之上,再對(duì)該分片進(jìn)行加鎖之后再讀寫。分片定位時(shí),常用有BKDR, FNV32等hash算法得到key的hash值。

func New() ConcurrentMap {
  // SHARD_COUNT 默認(rèn)32個(gè)分片
  m := make(ConcurrentMap, SHARD_COUNT)
  for i := 0; i  SHARD_COUNT; i++ {
    m[i] = ConcurrentMapShared{
      items: make(map[string]interface{}),
    }
  }
  return m
}

在初始化好分片后, 對(duì)分片上的數(shù)據(jù)進(jìn)行讀寫時(shí)就需要用hash取模進(jìn)行分段定位來確認(rèn)即將要讀寫的分片。

獲取段定位

func (m ConcurrentMap) GetShard(key string) *ConcurrentMapShared {
  return m[uint(fnv32(key))%uint(SHARD_COUNT)]
}

// FNV hash
func fnv32(key string) uint32 {
  hash := uint32(2166136261)
  const prime32 = uint32(16777619)
  for i := 0; i  len(key); i++ {
    hash *= prime32
    hash ^= uint32(key[i])
  }
  return hash
}

之后對(duì)于map的GET SET 就簡單順利成章的完成

Set And Get

func (m ConcurrentMap) Set(key string, value interface{}) {
  shard := m.GetShard(key) // 段定位找到分片
  shard.Lock()       // 分片上鎖
  shard.items[key] = value // 分片操作 
  shard.Unlock()       // 分片解鎖
}

func (m ConcurrentMap) Get(key string) (interface{}, bool) {
  shard := m.GetShard(key)
  shard.RLock()
  val, ok := shard.items[key]
  shard.RUnlock()
  return val, ok
}

由此一個(gè)分段鎖Map就實(shí)現(xiàn)了, 但是比起普通的Map, 常用到的方法比如獲取所有key, 獲取所有Val 操作是要比原生Map復(fù)雜的,因?yàn)橐闅v每一個(gè)分片的每一個(gè)數(shù)據(jù), 好在golang的并發(fā)特性使得解決這類問題變得非常簡單

Keys

// 統(tǒng)計(jì)當(dāng)前分段map中item的個(gè)數(shù)
func (m ConcurrentMap) Count() int {
  count := 0
  for i := 0; i  SHARD_COUNT; i++ {
    shard := m[i]
    shard.RLock()
    count += len(shard.items)
    shard.RUnlock()
  }
  return count
}

// 獲取所有的key
func (m ConcurrentMap) Keys() []string {
  count := m.Count()
  ch := make(chan string, count)

  // 每一個(gè)分片啟動(dòng)一個(gè)協(xié)程 遍歷key
  go func() {
    wg := sync.WaitGroup{}
    wg.Add(SHARD_COUNT)
    for _, shard := range m {

      go func(shard *ConcurrentMapShared) {
        defer wg.Done()
        
        shard.RLock()

        // 每個(gè)分片中的key遍歷后都寫入統(tǒng)計(jì)用的channel
        for key := range shard.items {
          ch - key
        }

        shard.RUnlock()
      }(shard)
    }
    wg.Wait()
    close(ch)
  }()

  keys := make([]string, count)
  // 統(tǒng)計(jì)各個(gè)協(xié)程并發(fā)讀取Map分片的key
  for k := range ch {
    keys = append(keys, k)
  }
  return keys
}

這里寫了一個(gè)benchMark來對(duì)該分段鎖Map和原生的Map加鎖方式進(jìn)行壓測, 場景為將一萬個(gè)不重復(fù)的鍵值對(duì)同時(shí)以100萬次寫和100萬次讀,分別進(jìn)行5次壓測, 如下壓測代碼

func BenchmarkMapShared(b *testing.B) {
  num := 10000
  testCase := genNoRepetTestCase(num) // 10000個(gè)不重復(fù)的鍵值對(duì)
  m := New()
  for _, v := range testCase {
    m.Set(v.Key, v.Val)
  }
  b.ResetTimer()

  for i := 0; i  5; i++ {
    b.Run(strconv.Itoa(i), func(b *testing.B) {

      b.N = 1000000

      wg := sync.WaitGroup{}
      wg.Add(b.N * 2)
      for i := 0; i  b.N; i++ {
        e := testCase[rand.Intn(num)]

        go func(key string, val interface{}) {
          m.Set(key, val)
          wg.Done()
        }(e.Key, e.Val)

        go func(key string) {
          _, _ = m.Get(key)
          wg.Done()
        }(e.Key)

      }
      wg.Wait()
    })
  }
}

原生Map加鎖壓測結(jié)果

分段鎖壓測結(jié)果

可以看出在將鎖的粒度細(xì)化后再面對(duì)大量需要控制并發(fā)安全的訪問時(shí),分段鎖Map的耗時(shí)比原生Map加鎖要快3倍有余

Sync.Map

go1.9之后加入了支持并發(fā)安全的Map sync.Map, sync.Map 通過一份只使用原子操作的數(shù)據(jù)和一份冗余了只讀數(shù)據(jù)的加鎖數(shù)據(jù)實(shí)現(xiàn)一定程度上的讀寫分離,使得大多數(shù)讀操作和更新操作是原子操作,寫入新數(shù)據(jù)才加鎖的方式來提升性能。以下是 sync.Map源碼剖析, 結(jié)構(gòu)體中的注釋都會(huì)在具體實(shí)現(xiàn)代碼中提示相呼應(yīng)

type Map struct {
  // 保護(hù)dirty的鎖
  mu Mutex            
  // 只讀數(shù)據(jù)(修改采用原子操作)
  read atomic.Value        
  // 包含只讀中所有數(shù)據(jù)(冗余),寫入新數(shù)據(jù)時(shí)也在dirty中操作
  dirty map[interface{}]*entry 
  // 當(dāng)原子操作訪問只讀read時(shí)找不到數(shù)據(jù)時(shí)會(huì)去dirty中尋找,此時(shí)misses+1,dirty及作為存儲(chǔ)新寫入的數(shù)據(jù),又冗余了只讀結(jié)構(gòu)中的數(shù)據(jù),所以當(dāng)misses > dirty 的長度時(shí), 會(huì)將dirty升級(jí)為read,同時(shí)將老的dirty置nil
  misses int 
}

// Map struct 中的 read 就是readOnly 的指針
type readOnly struct {
  // 基礎(chǔ)Map
  m  map[interface{}]*entry 
  // 用于表示當(dāng)前dirty中是否有read中不存在的數(shù)據(jù), 在寫入數(shù)據(jù)時(shí), 如果發(fā)現(xiàn)dirty中沒有新數(shù)據(jù)且dirty為nil時(shí),會(huì)將read中未被刪除的數(shù)據(jù)拷貝一份冗余到dirty中, 過程與Map struct中的 misses相呼應(yīng)
  amended bool 
}

// 數(shù)據(jù)項(xiàng)
type entry struct {
  p unsafe.Pointer 
}

// 用于標(biāo)記數(shù)據(jù)項(xiàng)已被刪除(主要保證數(shù)據(jù)冗余時(shí)的并發(fā)安全)
// 上述Map結(jié)構(gòu)中說到有一個(gè)將read數(shù)據(jù)拷貝冗余至dirty的過程, 因?yàn)閯h除數(shù)據(jù)項(xiàng)是將*entry置nil, 為了避免冗余過程中因并發(fā)問題導(dǎo)致*entry改變而影響到拷貝后的dirty正確性,所以sync.Map使用expunged來標(biāo)記entry是否被刪除
var expunged = unsafe.Pointer(new(interface{}))

在下面sync.Map具體實(shí)現(xiàn)中將會(huì)看到很多“雙檢查”代碼,因?yàn)橥ㄟ^原子操作獲取的值可能在進(jìn)行其他非原子操作過程中已改變,所以再非原子操作后需要使用之前原子操作獲取的值需要再次進(jìn)行原子操作獲取。

compareAndSwap 交換并比較, 用于在多線程編程中實(shí)現(xiàn)不被打斷的數(shù)據(jù)交換操作,從而避免多線程同時(shí)改寫某一數(shù)據(jù)時(shí)導(dǎo)致數(shù)據(jù)不一致問題。

sync.Map Write

func (m *Map) Store(key, value interface{}) {
  // 先不上鎖,而是從只讀數(shù)據(jù)中按key讀取, 如果已存在以compareAndSwap操作進(jìn)行覆蓋(update)
  read, _ := m.read.Load().(readOnly)
  if e, ok := read.m[key]; ok  e.tryStore(value) {
    return
  }
  
  m.mu.Lock()
  // 雙檢查獲取read
  read, _ = m.read.Load().(readOnly)
  // 如果data在read中,更新entry
  if e, ok := read.m[key]; ok {
    // 如果原子操作讀到的數(shù)據(jù)是被標(biāo)記刪除的, 則視為新數(shù)據(jù)寫入dirty
    if e.unexpungeLocked() {
      m.dirty[key] = e
    }
    // 原子操作寫新數(shù)據(jù)
    e.storeLocked(value)
  } else if e, ok := m.dirty[key]; ok {
    // 原子操作寫新數(shù)據(jù)
    e.storeLocked(value)
  } else {
    // 新數(shù)據(jù) 
    // 當(dāng)dirty中沒有新數(shù)據(jù)時(shí),將read中數(shù)據(jù)冗余到dirty
    if !read.amended {
      m.dirtyLocked()
      m.read.Store(readOnly{m: read.m, amended: true})
    }
    
    m.dirty[key] = newEntry(value)
  }
  m.mu.Unlock()
}

func (e *entry) tryStore(i *interface{}) bool {
  p := atomic.LoadPointer(e.p)
  if p == expunged {
    return false
  }
  for {
    if atomic.CompareAndSwapPointer(e.p, p, unsafe.Pointer(i)) {
      return true
    }
    p = atomic.LoadPointer(e.p)
    if p == expunged {
      return false
    }
  }
}


// 在dirty中沒有比read多出的新數(shù)據(jù)時(shí)觸發(fā)冗余
func (m *Map) dirtyLocked() {
  if m.dirty != nil {
    return
  }

  read, _ := m.read.Load().(readOnly)
  m.dirty = make(map[interface{}]*entry, len(read.m))
  for k, e := range read.m {
    // 檢查entry是否被刪除, 被刪除的數(shù)據(jù)不冗余
    if !e.tryExpungeLocked() {
      m.dirty[k] = e
    }
  }
}

func (e *entry) tryExpungeLocked() (isExpunged bool) {
  p := atomic.LoadPointer(e.p)
  for p == nil {
    // 將被刪除(置nil)的數(shù)據(jù)以cas原子操作標(biāo)記為expunged(防止因并發(fā)情況下其他操作導(dǎo)致冗余進(jìn)dirty的數(shù)據(jù)不正確)
    if atomic.CompareAndSwapPointer(e.p, nil, expunged) {
      return true
    }
    p = atomic.LoadPointer(e.p)
  }
  return p == expunged
}

sync.Map Read

func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
  read, _ := m.read.Load().(readOnly)
  e, ok := read.m[key]

  // 只讀數(shù)據(jù)中沒有,并且dirty有比read多的數(shù)據(jù),加鎖在dirty中找
  if !ok  read.amended {
    m.mu.Lock()
    // 雙檢查, 因?yàn)樯湘i之前的語句是非原子性的
    read, _ = m.read.Load().(readOnly)
    e, ok = read.m[key]
    if !ok  read.amended {
      // 只讀中沒有讀取到的次數(shù)+1
      e, ok = m.dirty[key]
      // 檢查是否達(dá)到觸發(fā)dirty升級(jí)read的條件
      m.missLocked()
    }
    m.mu.Unlock()
  }
  if !ok {
    return nil, false
  }
  // atomic.Load 但被標(biāo)記為刪除的會(huì)返回nil
  return e.load()
}

func (m *Map) missLocked() {
  m.misses++
  if m.misses  len(m.dirty) {
    return
  }
  m.read.Store(readOnly{m: m.dirty})
  m.dirty = nil
  m.misses = 0
}

sync.Map DELETE

func (m *Map) Delete(key interface{}) {
  read, _ := m.read.Load().(readOnly)
  e, ok := read.m[key]
  // 只讀中不存在需要到dirty中去刪除
  if !ok  read.amended {
    m.mu.Lock() 
    // 雙檢查, 因?yàn)樯湘i之前的語句是非原子性的
    read, _ = m.read.Load().(readOnly)
    e, ok = read.m[key]
    if !ok  read.amended {
      delete(m.dirty, key)
    }
    m.mu.Unlock()
  }
  if ok {
    e.delete()
  }
}

func (e *entry) delete() (hadValue bool) {
  for {
    p := atomic.LoadPointer(e.p)
    if p == nil || p == expunged {
      return false
    }
    if atomic.CompareAndSwapPointer(e.p, p, nil) {
      return true
    }
  }
}

同樣以剛剛壓測原生加鎖Map和分段鎖的方式來壓測sync.Map

壓測平均下來sync.Map和分段鎖差別不大,但是比起分段鎖, sync.Map則將鎖的粒度更加的細(xì)小到對(duì)數(shù)據(jù)的狀態(tài)上,使得大多數(shù)據(jù)可以無鎖化操作, 同時(shí)比分段鎖擁有更好的拓展性,因?yàn)榉侄捂i使用前總是要定一個(gè)分片數(shù)量, 在做擴(kuò)容或者縮小時(shí)很麻煩, 但要達(dá)到sync.Map這種性能既好又能動(dòng)態(tài)擴(kuò)容的程度,代碼就相對(duì)復(fù)雜很多。

還有注意在使用sync.Map時(shí)切忌不要將其拷貝, go源碼中有對(duì)sync.Map注釋到” A Map must not be copied after first use.”因?yàn)楫?dāng)sync.Map被拷貝之后, Map類型的dirty還是那個(gè)map 但是read 和 鎖卻不是之前的read和鎖(都不在一個(gè)世界你拿什么保護(hù)我), 所以必然導(dǎo)致并發(fā)不安全(為了寫博我把sync.Map代碼復(fù)制出來一份把私有成員改成可外部訪問的打印指針)

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • Golang 語言map底層實(shí)現(xiàn)原理解析
  • golang映射Map的方法步驟
  • Golang 使用map需要注意的幾個(gè)點(diǎn)
  • golang中使用sync.Map的方法
  • Golang Map實(shí)現(xiàn)賦值和擴(kuò)容的示例代碼
  • golang中range在slice和map遍歷中的注意事項(xiàng)
  • Golang自定義結(jié)構(gòu)體轉(zhuǎn)map的操作

標(biāo)簽:吐魯番 許昌 德宏 保定 東營 常州 曲靖 貴州

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《golang 并發(fā)安全Map以及分段鎖的實(shí)現(xiàn)方法》,本文關(guān)鍵詞  golang,并發(fā),安全,Map,以及,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《golang 并發(fā)安全Map以及分段鎖的實(shí)現(xiàn)方法》相關(guān)的同類信息!
  • 本頁收集關(guān)于golang 并發(fā)安全Map以及分段鎖的實(shí)現(xiàn)方法的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    国产精品爱久久久久久久小说| 亚洲欧美成aⅴ人在线观看| 日本aⅴ精品一区二区三区| 日本高清久久天堂| 久久中文字幕在线观看| 九色视频一区| 国产真实乱偷精品视频免| 亚洲欧美日韩中文视频| freesex欧美| 日韩精品免费一区二区| 午夜激情成人网| 国产日韩高清一区二区三区在线| 久久gogo国模啪啪裸体| 午夜国产一区| 成人3d动漫在线观看| 国产一级做a爱免费视频| 日韩三级av高清片| 亚洲一区二区三区乱码aⅴ蜜桃女| av色男福利网| 91精品麻豆日日躁夜夜躁| 色乱码一区二区三区熟女| 9l视频自拍蝌蚪9l视频成人| 黄网在线观看网址入口| av资源网站在线观看| 中文一区二区| 26uuu亚洲| 免费看黄裸体一级大秀欧美| 宅男66日本亚洲欧美视频| 国产精品av电影| 91好吊色国产欧美日韩在线| 国产又粗又猛又爽又黄的| 激情另类小说区图片区视频区| 亚洲欧美日韩偷拍| 狠狠躁夜夜躁av无码中文幕| 特级西西444www高清大视频| 美女呻吟一区| 久久精品国产理论片免费| 欧美黑人ⅹxxx另类猛交| 免费看黄色a级片| 在线观看免费亚洲| 精品女同一区二区三区在线观看| 国产肉丝袜一区二区| 另类图片亚洲色图| 色欲狠狠躁天天躁无码中文字幕| 一道本无吗一区| 欧美日韩不卡| 国产福利在线播放麻豆| 欧美高清videos高潮hd| 亚洲韩日在线| 丰满岳妇乱一区二区三区| 亚洲香肠在线观看| 国产精品久久久久久一区二区三区| 国产精品波多野结衣| 日本一区二区三区电影免费观看| 91久久偷偷做嫩草影院电| 国产又爽又黄无码无遮挡在线观看| 成年女人18级毛片毛片免费| 一区二区av| 欧美综合视频在线| 91香蕉视频在线观看视频| 99re热这里只有精品视频| 天天色天天爽| 18+激情视频在线| 亚洲成a人片在线不卡一二三区| 久久国产精品成人免费观看的软件| 亚洲电影av在线| 精品少妇爆乳无码av无码专区| 伊人网站在线| 精品亚洲第一| 久久综合免费视频| 一区高清视频| 懂色av一区二区三区蜜臀| 欧美国产日韩中文字幕在线| 国产香蕉精品视频| 国产一区视频在线播放| 国产日韩欧美精品一区二区三区| 在线观看免费中文字幕| 国产精品视频免费播放| 一本久道在线| 日本精品久久久久中文| 人人妻人人澡人人爽精品欧美一区| 欧美国产精品一区二区三区| 韩国成人福利片在线播放| 国产日韩一区欧美| 女人裸体性做爰全过| 日本亚洲欧美美色| 狠狠爱在线视频一区| 久久精品一区二区三区不卡免费视频| 黄色av网址在线观看| 香蕉视频黄色片| fc2ppv在线观看| 国产日产欧美a一级在线| 蜜桃av一区二区在线观看| 91精品国产91久久久久游泳池| 麻豆成人小视频| 国产精品久久久久久久久借妻| 国产国产国产国产国产国产| 国产在线视频不卡二| 2019最新中文字幕| 午夜国产福利在线| 亚洲第一成年人网站| 在线观看免费网站| 涩涩视频免费网站| 美女久久久精品| 亚洲专区一二三| 美腿丝袜亚洲一区| 在线免费看黄色| 亚洲美女欧洲| 日本成人动漫在线观看| 在线看黄的网站| 成人激情视频网| 你懂的亚洲视频| 国产女人伦码一区二区三区不卡| 大片免费播放在线视频| 日韩和的一区二在线| 欧美精品中文字幕一区| 亚洲福利久久| 男同互操gay射视频在线看| 亚洲成人中文字幕| 九九九久久久| aaa毛片在线观看| 中文字幕视频在线观看| 成人性生交大片免费看视频r| 亚洲 自拍 另类小说综合图区| av在线播放天堂| 国产午夜精品福利| 在线你懂的视频| 久久精品视频一区二区三区| 天天色天天射综合网| 欧美激情网址| 青青一区二区三区| 欧美疯狂爱爱xxxxbbbb| 欧美 日韩 国产一区二区在线视频| 国产精品自拍首页| 四虎永久在线观看| 尤物99国产成人精品视频| 无限资源日本好片| 老司机午夜av| 成人美女视频| 中文字幕免费在线观看视频一区| 国内少妇毛片视频| 国产99在线播放| 久久大综合网| 97人澡人人添人人爽欧美| 精品女厕一区二区三区| 我要色综合中文字幕| 色就是色亚洲色图| 色屁屁www国产馆在线观看| 国产精品一二三四五区| 二区三区不卡不卡视频| 秋霞网一区二区| 国产精品一码二码三码在线| 色婷婷综合久久久久中文| 2023国产精华国产精品| 成人免费视频视频在| 1024亚洲合集| 午夜剧场在线免费观看| 中文字幕的av| 中文字幕超清在线免费观看| 五级黄高潮片90分钟视频| 制服视频三区第一页精品| av在线亚洲一区| 成人爽a毛片免费啪啪红桃视频| 日韩精品一卡| 国产 日韩 欧美 综合 一区| 天海翼精品一区二区三区| 91在线码无精品| 精品国产乱码久久久久久樱花| 性欧美xxx69hd高清| 国产精品久久久| 西野翔中文久久精品国产| 精品久久国产老人久久综合| 国产精品伦一区二区三区| 久久久国产精品一区二区中文| 国产亚洲一区二区三区在线播放| 香蕉久久久久久av成人| 中文字幕在线观看日| 国产精品密蕾丝袜| 狠狠狠色丁香婷婷综合激情| 亚洲欧美日本视频在线观看| 美女视频黄a大片欧美| 欧美俄罗斯乱妇| 3p视频在线观看| 伊人五月天婷婷| 欧美日韩国产小视频在线观看| 欧美第一精品| 成人免费电影网址| 亚洲精品**中文毛片| 亚洲精品美女免费| 18深夜视频在线观看| 日韩三级网址| 日本精品一区在线| 亚洲人成影视在线观看| 在线播放中文一区| 亚洲日本在线观看视频| 日韩电影免费在线观看中文字幕| 免费av片风间由美在线| 欧美大陆国产| 国产成人精品日本亚洲| 精品一级少妇久久久久久久| 91国内精品久久久| 欧美日韩精品电影| 国产精品麻豆成人av电影艾秋| 深夜视频一区二区| 香蕉国产精品偷在线观看不卡| 日韩成人高清在线| 成人h动漫精品一区二区器材| 色偷偷一区二区三区| 野花社区视频在线观看| 五月婷婷丁香在线| 色琪琪综合男人的天堂aⅴ视频| 禁网站在线观看免费视频| 亚洲一区二区四区| 日本午夜精品久久久久| 一级黄色在线| 国产精品第6页| 亚洲欧洲一二区| 成人羞羞视频免费| 国产丝袜在线观看视频| 成人黄色电影在线| 欧美精品久久久久久久久46p| 欧美嫩在线观看| 色综合桃花网| 国产福利片在线观看| 亚洲人成在线播放网站岛国| 深夜福利网站在线观看| 免费成人高清在线视频theav| 日本精品久久久久影院| free性亚洲| 91精品在线一区二区| 亚洲va久久久噜噜噜久久狠狠| 亚洲免费三区一区二区| 国产一二三区在线| 欧一区二区三区| 99tv成人| 99re99热| 色在线免费观看| 韩国精品一区二区三区六区色诱| 中文字幕在线观看视频网站| 欧美一区二区在线视频观看| 欧美日韩激情一区二区| 国内精品久久久久久久久久久| 超碰一区二区| 亚洲国产毛片完整版| 欧美黑吊大战白妞| 国产福利资源一区| 精品国产一区二区三区麻豆免费观看完整版| 亚洲精品无人区| 欧美黑人xxx| 91精品国产乱码久久久久久| 国产熟女高潮视频| www.xxx麻豆| 操91在线视频| 欧美一级xxx| 懂色av蜜臀av粉嫩av永久| 一级毛片视频在线| 日韩av片在线播放| 在线一区二区三区视频| 怡红院av在线| 不卡的免费av| 久久激情五月激情| 国产最顶级的黄色片在线免费观看| 久久久精品综合| 91高潮在线观看| 超碰在线最新| 高潮无码精品色欲av午夜福利| 在线播放国产一区中文字幕剧情欧美| av黄色在线播放| 日韩精品免费在线| 久久亚洲精品小早川怜子66| 亚洲综合免费观看高清在线观看| 亚洲GV成人无码久久精品| 亚洲一级特黄| 韩国三级av在线免费观看| 国产性xxxx| 国产在线精品观看| www..com.cn蕾丝视频在线观看免费版| 免费国产羞羞网站美图| xfplay资源站色先锋在线观看| www,av在线| 欧美精品成人一区二区三区四区| 9i看片成人免费高清| aⅴ在线视频男人的天堂| 日本黄色电影网站| 亚洲人成电影网站色| 久久一综合视频| www.欧美色| 国产乱码精品一区二区三区日韩精品| 91精品国产91久久久久久一区二区| 中文在线字幕av| 欧美在线不卡一区| 黄色亚洲免费| www国产无套内射com| 欧美a级黄色大片| 非洲黑人最猛性xxxx交| chinese全程对白| 色婷婷久久久亚洲一区二区三区| 7777精品伊人久久久大香线蕉的| 在线看视频你懂的| 国产高中女学生第一次| 亚洲精品老司机| 久久久久久久久岛国免费| 一区二区电影在线观看| 国产91精品在线观看| 亚洲欧美综合另类在线卡通| 色天天久久综合婷婷女18| 国产在线看一区| 麻豆精品国产| 成年网站在线视频网站| 国产综合视频在线观看| 免费人成福利播放| 精品国产乱码久久久久久88av| 一区二区三区免费观看| 国产亚洲色婷婷久久99精品| 欧美老少配视频| 视频一区中文| 欧美一区在线观看视频| 欧美天堂在线视频| 亚洲精品自在久久| 天天操天天干天天做| 亚洲成av人影片在线观看| 亚洲男人天堂2021| 国产极品一区二区| 久久综合九色综合欧美狠狠| 天天爱天天做天天操| 欧美第一黄色网| 无码人妻av免费一区二区三区| 中文字幕在线久热精品|