青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Fork me on GitHub
隨筆 - 215  文章 - 13  trackbacks - 0
<2015年11月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345


專注即時通訊及網游服務端編程
------------------------------------
Openresty 官方模塊
Openresty 標準模塊(Opm)
Openresty 三方模塊
------------------------------------
本博收藏大部分文章為轉載,并在文章開頭給出了原文出處,如有再轉,敬請保留相關信息,這是大家對原創作者勞動成果的自覺尊重!!如為您帶來不便,請于本博下留言,謝謝配合。

常用鏈接

留言簿(1)

隨筆分類

隨筆檔案

相冊

Awesome

Blog

Book

GitHub

Link

搜索

  •  

積分與排名

  • 積分 - 220944
  • 排名 - 117

最新評論

閱讀排行榜

本文轉自:http://blog.csdn.net/yue7603835/article/details/44309409
轉載請自覺標明原文出處
Golang :不要通過共享內存來通信,而應該通過通信來共享內存。這句風靡在Go社區的話,說的就是 goroutine中的 channel .......
他在go并發編程中充當著 類型安全的管道作用。
1、通過golang中的 goroutine 與sync.Mutex進行 并發同步
import( 
    "fmt"
    "sync"
    "runtime"
)
var count int =0;
func counter(lock * sync.Mutex){
      lock.Lock()
      count++
      fmt.Println(count)
      lock.Unlock()
}
func main(){
   lock:=&sync.Mutex{}
   for i:=0;i<10;i++{
      //傳遞指針是為了防止 函數內的鎖和 調用鎖不一致
      go counter(lock)  
     }
   for{
      lock.Lock()
      c:=count
      lock.Unlock()
      ///把時間片給別的goroutine  未來某個時刻運行該routine
      runtime.Gosched()
      if c>=10{
        fmt.Println("goroutine end")
        break
        }
   }    
}
2、goroutine之間通過 channel進行通信,channel是和類型相關的 可以理解為  是一種類型安全的管道。
簡單的channel 使用
package main  
import "fmt"
func Count(ch chan int) {
    ch <- 1  
    fmt.Println("Counting")
}
func main() {
    chs := make([]chan int, 10)
for i := 0; i < 10; i++ {
        chs[i] = make(chan int)
  go Count(chs[i])
  fmt.Println("Count",i)
    }
for i, ch := range chs {
  <-ch
  fmt.Println("Counting",i)
    }  
3、Go語言中的select是語言級內置  非堵塞
select {
case <-chan1: // 如果chan1成功讀到數據,則進行該case處理語句  
case chan2 <- 1: // 如果成功向chan2寫入數據,則進行該case處理語句  
default: // 如果上面都沒有成功,則進入default處理流程  
}
可以看出,select不像switch,后面并不帶判斷條件,而是直接去查看case語句。每個
case語句都必須是一個面向channel的操作。比如上面的例子中,第一個case試圖從chan1讀取
一個數據并直接忽略讀到的數據,而第二個case則是試圖向chan2中寫入一個整型數1,如果這
兩者都沒有成功,則到達default語句。 
4、channel 的帶緩沖讀取寫入
之前我們示范創建的都是不帶緩沖的channel,這種做法對于傳遞單個數據的場景可以接受,
但對于需要持續傳輸大量數據的場景就有些不合適了。接下來我們介紹如何給channel帶上緩沖,
從而達到消息隊列的效果。
要創建一個帶緩沖的channel,其實也非常容易:
c := make(chan int, 1024)
在調用make()時將緩沖區大小作為第二個參數傳入即可,比如上面這個例子就創建了一個大小
為1024的int類型channel,即使沒有讀取方,寫入方也可以一直往channel里寫入,在緩沖區被
填完之前都不會阻塞。
從帶緩沖的channel中讀取數據可以使用與常規非緩沖channel完全一致的方法,但我們也可
以使用range關鍵來實現更為簡便的循環讀取:
for i := range c {
    fmt.Println("Received:", i)
5、用goroutine模擬生產消費者
package main
import "fmt"
import "time"
func Producer (queue chan<- int){
        for i:= 0; i < 10; i++ {
                queue <- i  
                }
}
func Consumer( queue <-chan int){
        for i :=0; i < 10; i++{
                v := <- queue
                fmt.Println("receive:", v)
        }
}
func main(){
        queue := make(chan int, 1)
        go Producer(queue)
        go Consumer(queue)
        time.Sleep(1e9) //讓Producer與Consumer完成
}
6、 通過make 創建通道 
 make(c1 chan int)   創建的是 同步channel ...讀寫完全對應
make(c1 chan int ,10) 闖進帶緩沖的通道 上來可以寫10次
7、隨機向通道中寫入0或者1 
package main
import "fmt"
import "time"
func main(){
       ch := make(chan int, 1)
 for {
   ///不停向channel中寫入 0 或者1
  select {
   case ch <- 0:
   case ch <- 1:
  }
    //從通道中取出數據
    i := <-ch
    fmt.Println("Value received:",i)
    time.Sleep(1e8)
    }
}
8、帶緩沖的channel 
之前創建的都是不帶緩沖的channel,這種做法對于傳遞單個數據的場景可以接受,
但對于需要持續傳輸大量數據的場景就有些不合適了。接下來我們介紹如何給channel帶上緩沖,
從而達到消息隊列的效果。
要創建一個帶緩沖的channel,其實也非常容易:
c := make(chan int, 1024)
在調用make()時將緩沖區大小作為第二個參數傳入即可,比如上面這個例子就創建了一個大小
為1024的int類型channel,即使沒有讀取方,寫入方也可以一直往channel里寫入,在緩沖區被
填完之前都不會阻塞。
從帶緩沖的channel中讀取數據可以使用與常規非緩沖channel完全一致的方法,但我們也可
以使用range關鍵來實現更為簡便的循環讀取:
for i := range c {
    fmt.Println("Received:", i)
}
////////////////////////////////////////下面是測試代碼////////////////////////////////////
package main
import "fmt"
import "time"
func A(c chan int){
 for i:=0;i<10;i++{
        c<- i
    }
}
func B(c chan int){
 for val:=range c {
      fmt.Println("Value:",val)  
    }
}
func main(){
    chs:=make(chan int,10)
    //只要有通道操作一定要放到goroutine中否則 會堵塞當前的主線程 并且導致程序退出
    //對于同步通道 或者帶緩沖的通道 一定要封裝成函數 使用 goroutine 包裝
    go A(chs)
    go B(chs)
    time.Sleep(1e9)
}
9、關于創建多個goroutine具體到go語言會創建多少個線程
import "os"
func main() {
    for i:=0; i<20; i++ {
        go func() {
            for {
                b:=make([]byte, 10)
                os.Stdin.Read(b) // will block
            }
        }()
    }
    select{}
}
會產生21個線程:
runtime scheduler(src/pkg/runtime/proc.c)會維護一個線程池,當某個goroutine被block后,scheduler會創建一個新線程給其他ready的goroutine
GOMAXPROCS控制的是未被阻塞的所有goroutine被multiplex到多少個線程上運行
10、在channel中也是可以傳遞channel的,Go語言的channel和map  slice等一樣都是原生類型
需要注意的是,在Go語言中channel本身也是一個原生類型,與map之類的類型地位一樣,因
此channel本身在定義后也可以通過channel來傳遞。
我們可以使用這個特性來實現*nix上非常常見的管道(pipe)特性。管道也是使用非常廣泛
的一種設計模式,比如在處理數據時,我們可以采用管道設計,這樣可以比較容易以插件的方式
增加數據的處理流程。
下面我們利用channel可被傳遞的特性來實現我們的管道。 為了簡化表達, 我們假設在管道中
傳遞的數據只是一個整型數,在實際的應用場景中這通常會是一個數據塊。
首先限定基本的數據結構:
type PipeData struct {
    value int
    handler func(int) int
    next chan int
}
然后我們寫一個常規的處理函數。我們只要定義一系列PipeData的數據結構并一起傳遞給
這個函數,就可以達到流式處理數據的目的:
func handle(queue chan *PipeData) {
for data := range queue {
        data.next <- data.handler(data.value)
    }
}
11、我們默認創建的是雙向通道,單向通道沒有意義,但是我們卻可以通過強制轉換 將雙向通道 轉換成為單向通道 。
var ch1 chan int  // ch1是一個正常的channel,不是單向的  
var ch2 chan<- float64// ch2是單向channel,只用于寫float64數據
var ch3 <-chan int // ch3是單向channel,只用于讀取int數據 
channel是一個原生類型,因此不僅 支持被傳遞,還支持類型轉換。只有在介紹了單向channel的概念后,讀者才會明白類型轉換對于 
channel的意義:就是在單向channel和雙向channel之間進行轉換。
示例如下:
ch4 := make(chan int)
ch5 := <-chan int(ch4) // ch5就是一個單向的讀取channel
ch6 := chan<- int(ch4) // ch6 是一個單向的寫入channel
基于ch4,我們通過類型轉換初始化了兩個單向channel:單向讀的ch5和單向寫的ch6。 
從設計的角度考慮,所有的代碼應該都遵循“最小權限原則” , 
從而避免沒必要地使用泛濫問題, 進而導致程序失控。 寫過C++程序的讀者肯定就會聯想起const 指針的用法。非const指針具備const指針的所有功能,將一個指針設定為const就是明確告訴 
函數實現者不要試圖對該指針進行修改。單向channel也是起到這樣的一種契約作用。
下面我們來看一下單向channel的用法:
func Parse(ch <-chan int) {
for value := range ch {
        fmt.Println("Parsing value", value)  
    }
}
除非這個函數的實現者無恥地使用了類型轉換,否則這個函數就不會因為各種原因而對ch 進行寫,避免在ch中出現非期望的數據,從而很好地實踐最小權限原則。
12、只讀只寫 單向 channel 代碼例子    遵循權限最小化的原則
package main
import "fmt"
import "time"
//接受一個參數 是只允許讀取通道  除非直接強制轉換 要么你只能從channel中讀取數據
func sCh(ch <-chan int){
   for val:= range ch {
     fmt.Println(val)
   }
}
func main(){
    //創建一個帶100緩沖的通道 可以直接寫入 而不會導致 主線程堵塞
    dch:=make(chan int,100)
    for i:=0;i<100;i++{
      dch<- i  
    }
    //傳遞進去 只讀通道
    go sCh(dch)
    time.Sleep(1e9)
}
13、channel的關閉,以及判斷channel的關閉
關閉channel非常簡單,直接使用Go語言內置的close()函數即可:
close(ch)
在介紹了如何關閉channel之后,我們就多了一個問題:如何判斷一個channel是否已經被關
閉?我們可以在讀取的時候使用多重返回值的方式:
x, ok := <-ch
這個用法與map中的按鍵獲取value的過程比較類似,只需要看第二個bool返回值即可,如
果返回值是false則表示ch已經被關閉。
14、Go的多核并行化編程    高性能并發編程 必須設置GOMAXPROCS 為最大核數目 這個值由runtime.NumCPU()獲取
在執行一些昂貴的計算任務時, 我們希望能夠盡量利用現代服務器普遍具備的多核特性來盡
量將任務并行化,從而達到降低總計算時間的目的。此時我們需要了解CPU核心的數量,并針對
性地分解計算任務到多個goroutine中去并行運行。
下面我們來模擬一個完全可以并行的計算任務:計算N個整型數的總和。我們可以將所有整
型數分成M份,M即CPU的個數。讓每個CPU開始計算分給它的那份計算任務,最后將每個CPU
的計算結果再做一次累加,這樣就可以得到所有N個整型數的總和:
type Vector []float64
// 分配給每個CPU的計算任務
func (v Vector) DoSome(i, n int, u Vector, c chan int) {
for ; i < n; i++ {
         v[i] += u.Op(v[i])
     }
     c <- 1       
// 發信號告訴任務管理者我已經計算完成了
}
const NCPU = 16     
// 假設總共有16核   
func (v Vector) DoAll(u Vector) {   
    c := make(chan int, NCPU)  // 用于接收每個CPU的任務完成信號   
for i := 0; i < NCPU; i++ {   
go v.DoSome(i*len(v)/NCPU, (i+1)*len(v)/NCPU, u, c)
    } 
// 等待所有CPU的任務完成
for i := 0; i < NCPU; i++ {   
<-c    // 獲取到一個數據,表示一個CPU計算完成了
    }
// 到這里表示所有計算已經結束
}
這兩個函數看起來設計非常合理。DoAll()會根據CPU核心的數目對任務進行分割,然后開
辟多個goroutine來并行執行這些計算任務。
是否可以將總的計算時間降到接近原來的1/N呢?答案是不一定。如果掐秒表(正常點的話,
應該用7.8節中介紹的Benchmark方法) ,會發現總的執行時間沒有明顯縮短。再去觀察CPU運行
狀態, 你會發現盡管我們有16個CPU核心, 但在計算過程中其實只有一個CPU核心處于繁忙狀態,
這是會讓很多Go語言初學者迷惑的問題。
官方的答案是,這是當前版本的Go編譯器還不能很智能地去發現和利用多核的優勢。雖然
我們確實創建了多個goroutine,并且從運行狀態看這些goroutine也都在并行運行,但實際上所有
這些goroutine都運行在同一個CPU核心上, 在一個goroutine得到時間片執行的時候, 其他goroutine
都會處于等待狀態。從這一點可以看出,雖然goroutine簡化了我們寫并行代碼的過程,但實際上
整體運行效率并不真正高于單線程程序。
在Go語言升級到默認支持多CPU的某個版本之前,我們可以先通過設置環境變量
GOMAXPROCS的值來控制使用多少個CPU核心。具體操作方法是通過直接設置環境變量
GOMAXPROCS的值,或者在代碼中啟動goroutine之前先調用以下這個語句以設置使用16個CPU
核心:
runtime.GOMAXPROCS(16)
到底應該設置多少個CPU核心呢,其實runtime包中還提供了另外一個函數NumCPU()來獲
取核心數。可以看到,Go語言其實已經感知到所有的環境信息,下一版本中完全可以利用這些
信息將goroutine調度到所有CPU核心上,從而最大化地利用服務器的多核計算能力。拋棄
GOMAXPROCS只是個時間問題。 
15、主動出讓時間片給其他 goroutine 在未來的某一時刻再來執行當前goroutine
我們可以在每個goroutine中控制何時主動出讓時間片給其他goroutine,這可以使用runtime
包中的Gosched()函數實現。
實際上,如果要比較精細地控制goroutine的行為,就必須比較深入地了解Go語言開發包中
runtime包所提供的具體功能。
16、Go中的同步
倡導用通信來共享數據,而不是通過共享數據來進行通信,但考慮
到即使成功地用channel來作為通信手段,還是避免不了多個goroutine之間共享數據的問題,Go
語言的設計者雖然對channel有極高的期望,但也提供了妥善的資源鎖方案。
17、Go中的同步鎖
倡導用通信來共享數據,而不是通過共享數據來進行通信,但考慮
到即使成功地用channel來作為通信手段,還是避免不了多個goroutine之間共享數據的問題,Go
語言的設計者雖然對channel有極高的期望,但也提供了妥善的資源鎖方案。
對于這兩種鎖類型, 任何一個Lock()或RLock()均需要保證對應有Unlock()或RUnlock()
調用與之對應,否則可能導致等待該鎖的所有goroutine處于饑餓狀態,甚至可能導致死鎖。鎖的
典型使用模式如下:
var l sync.Mutex  
func foo() {
l.Lock()  
//延遲調用 在函數退出 并且局部資源被釋放的時候 調用
defer l.Unlock()  
//...
}  
這里我們再一次見證了Go語言defer關鍵字帶來的優雅
18、全局唯一操作 sync.Once.Do()     sync.atomic原子操作子包
對于從全局的角度只需要運行一次的代碼,比如全局初始化操作,Go語言提供了一個Once
類型來保證全局的唯一性操作,具體代碼如下:
var a string
var once sync.Once  
func setup() {
a = "hello, world"
}  
func doprint() {
once.Do(setup)
print(a)  
}  
func twoprint() {
go doprint()
go doprint()  
}
如果這段代碼沒有引入Once, setup()將會被每一個goroutine先調用一次, 這至少對于這個
例子是多余的。在現實中,我們也經常會遇到這樣的情況。Go語言標準庫為我們引入了Once類
型以解決這個問題。once的Do()方法可以保證在全局范圍內只調用指定的函數一次(這里指
setup()函數) ,而且所有其他goroutine在調用到此語句時,將會先被阻塞,直至全局唯一的
once.Do()調用結束后才繼續。
這個機制比較輕巧地解決了使用其他語言時開發者不得不自行設計和實現這種Once效果的
難題,也是Go語言為并發性編程做了盡量多考慮的一種體現。
如果沒有once.Do(),我們很可能只能添加一個全局的bool變量,在函數setup()的最后
一行將該bool變量設置為true。在對setup()的所有調用之前,需要先判斷該bool變量是否已
經被設置為true,如果該值仍然是false,則調用一次setup(),否則應跳過該語句。實現代碼
var done bool = false
func setup() {
a = "hello, world" 
done = true
}     
func doprint() { 
if !done {
        setup()
    }   
print(a)  
}  
這段代碼初看起來比較合理, 但是細看還是會有問題, 因為setup()并不是一個原子性操作,
這種寫法可能導致setup()函數被多次調用,從而無法達到全局只執行一次的目標。這個問題的
復雜性也更加體現了Once類型的價值。
為了更好地控制并行中的原子性操作,sync包中還包含一個atomic子包,它提供了對于一
些基礎數據類型的原子操作函數,比如下面這個函數:
func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool)
就提供了比較和交換兩個uint64類型數據的操作。這讓開發者無需再為這樣的操作專門添加
Lock操作。
posted on 2017-06-02 10:58 思月行云 閱讀(338) 評論(0)  編輯 收藏 引用 所屬分類: Golang
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品中文字幕一区| 午夜精品短视频| 欧美大片一区| 亚洲一区二区三区在线看| 欧美成人有码| 亚洲福利在线看| 久久xxxx精品视频| 亚洲欧美日韩国产精品| 欧美午夜精品电影| 一本色道久久综合亚洲精品小说| 老色鬼精品视频在线观看播放| 亚洲欧美日本日韩| 国产一区二区三区免费在线观看| 亚洲欧美日本视频在线观看| 日韩午夜av电影| 欧美日韩中文字幕日韩欧美| 99视频在线观看一区三区| 亚洲精品国偷自产在线99热| 久久青青草原一区二区| 在线观看一区二区精品视频| 美女黄毛**国产精品啪啪| 久久夜色精品亚洲噜噜国产mv| 狠狠88综合久久久久综合网| 久久综合色综合88| 牛牛影视久久网| 一区二区免费在线观看| 一区二区欧美在线观看| 国产精品日韩电影| 开元免费观看欧美电视剧网站| 久久se精品一区二区| 尤物九九久久国产精品的分类| 欧美国产日韩一区二区在线观看| 女人香蕉久久**毛片精品| 日韩一级片网址| 亚洲一区免费看| 韩国一区二区三区美女美女秀| 久久综合久色欧美综合狠狠| 欧美99在线视频观看| 亚洲性xxxx| 久久精品盗摄| 日韩一级视频免费观看在线| 亚洲午夜激情在线| 在线观看亚洲专区| 亚洲视频在线观看三级| 亚洲一区二区三区四区中文 | 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 国产精品国产自产拍高清av王其 | 亚洲欧美日韩天堂| 精品二区久久| 日韩视频永久免费观看| 国内偷自视频区视频综合| 亚洲精品国产拍免费91在线| 国产伦理精品不卡| 亚洲三级电影在线观看| 国产在线一区二区三区四区| 亚洲欧洲日本在线| 红桃视频国产一区| 亚洲午夜久久久| 亚洲欧洲日本在线| 欧美一区二区三区在线| 一区二区免费在线视频| 久久亚洲国产成人| 欧美在线一级视频| 欧美日本国产精品| 欧美大片在线看免费观看| 国产美女诱惑一区二区| 91久久精品www人人做人人爽| 国产一区二区三区精品久久久| 亚洲第一毛片| 韩国精品在线观看| 午夜精品久久久久久| 亚洲国产高清视频| 欧美一区二视频| 欧美一区二区三区在线免费观看| 欧美大片一区| 欧美xart系列在线观看| 国产嫩草影院久久久久| 亚洲人成毛片在线播放女女| 在线不卡视频| 欧美在线观看网站| 欧美制服第一页| 国产精品久久久久毛片软件 | 亚洲精品免费网站| 亚洲二区在线| 久久精品国产91精品亚洲| 午夜视频久久久| 欧美性开放视频| 亚洲免费成人av| 一本一道久久综合狠狠老精东影业 | 亚洲女女女同性video| 一道本一区二区| 亚洲午夜av电影| 亚洲网站在线| 欧美日韩在线三级| 99re亚洲国产精品| 亚洲一区二区免费| 欧美午夜宅男影院在线观看| 日韩系列欧美系列| 亚洲午夜在线视频| 国产精品裸体一区二区三区| 亚洲色图制服丝袜| 欧美制服丝袜第一页| 国产亚洲欧美一区在线观看| 亚洲免费视频中文字幕| 欧美亚洲综合另类| 韩国在线视频一区| 嫩草成人www欧美| 99视频精品全部免费在线| 亚洲一区二区在线免费观看视频| 欧美日韩国语| 亚洲欧美激情视频| 免费观看亚洲视频大全| 亚洲精品久久久一区二区三区| 欧美激情一区二区三级高清视频| 亚洲日产国产精品| 欧美亚洲一区三区| 136国产福利精品导航网址| 欧美成人69| 亚洲午夜精品网| 媚黑女一区二区| 99视频一区| 国产无一区二区| 嫩草国产精品入口| 亚洲亚洲精品三区日韩精品在线视频| 欧美在线一二三| 亚洲精品欧美日韩专区| 国产精品v欧美精品v日韩精品| 欧美一级欧美一级在线播放| 欧美高清在线视频| 性欧美大战久久久久久久免费观看| 国产一区二区在线免费观看 | 久久国产成人| 亚洲国产裸拍裸体视频在线观看乱了 | 狂野欧美激情性xxxx| 亚洲日本黄色| 久久久在线视频| 一区二区av在线| 国产一区在线播放| 欧美日韩精品一区二区| 欧美一区二区三区的| 亚洲激情在线视频| 久久久久久91香蕉国产| 一区二区三区毛片| 黄色精品在线看| 国产精品理论片| 欧美精品久久久久久久免费观看| 亚洲制服欧美中文字幕中文字幕| 欧美国产日本| 久久久亚洲国产美女国产盗摄| 一片黄亚洲嫩模| 亚洲激情一区| 国内成人精品视频| 国产精品日本精品| 欧美日韩性视频在线| 欧美**字幕| 久久综合久久久久88| 欧美一区二区三区在线观看视频 | 欧美aⅴ99久久黑人专区| 亚洲一区国产视频| 亚洲美女av网站| 在线精品视频一区二区| 国产女人18毛片水18精品| 欧美三级午夜理伦三级中视频| 蜜桃av噜噜一区| 久久久精品欧美丰满| 午夜日韩视频| 亚洲欧美国产视频| 中文亚洲视频在线| 99国产精品视频免费观看一公开| 欧美激情视频网站| 欧美成人蜜桃| 欧美成人黄色小视频| 久热爱精品视频线路一| 久久久av水蜜桃| 久久久国产精品一区二区三区| 亚洲一区观看| 校园激情久久| 欧美一级欧美一级在线播放| 亚洲在线观看免费视频| 亚洲一区美女视频在线观看免费| 亚洲乱码国产乱码精品精可以看 | 亚洲福利一区| 亚洲国产导航| 99国产精品久久久久久久久久 | 日韩亚洲成人av在线| 亚洲三级影院| 一区二区福利| 午夜精品理论片| 欧美诱惑福利视频| 久久久亚洲综合| 免费成人高清在线视频| 欧美大片免费久久精品三p | 亚洲一区二区在线播放| 午夜在线精品| 久久久久久夜精品精品免费| 老鸭窝毛片一区二区三区| 欧美激情日韩| 一本色道久久综合亚洲精品不卡| 亚洲直播在线一区| 麻豆精品一区二区综合av |