亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

關于mfc線程 的退出問題、同步問題

2019-11-11 04:30:38
字體:
來源:轉載
供稿:網友
AfxBeginThread()函數的返回值是CWinThread* 指針,但是這個指針不能直接使用,因為這個指針會自動銷毀。如果道友直接使用了這個指針,那么當在操作這個指針時,若已被mfc銷毀,那么訪問違規將會到來。至于返回值的使用請看,我寫的一個mfc程序片段。[html] view plain copyCString strName = _T("");  CWinThread* pThread = NULL;  UINT CBcgTestDlg::ThreadWorkFunc(LPVOID lPvoid)  {            for (int n = 0; n < 10000; n++)      {          strName = _T("http://blog.csdn.net/windows_nt");          strName = strName + _T("/n");          TRACE(strName);      }            return 0;  }      void CBcgTestDlg::OnOK()   {      for (int n = 0; n < 10000; ++n)      {          if (pThread)          {              WaitForSingleObject(pThread->m_hThread, INFINITE);              delete pThread;          }                    pThread = AfxBeginThread(ThreadWorkFunc, NULL, 0, CREATE_SUSPENDED, NULL);          if (pThread)          {              pThread->m_bAutoDelete = FALSE;              pThread->ResumeThread();          }      }  }    

//現在可以放心的使用返回值pThread了,但是要記得在使用結束后記得調用delete pThread,釋放資源(CWinThread類中的線程句柄會在析構函數中自動釋放)。 線程同步的方式主要有:臨界區、互斥區、事件、信號量四種方式。一、

接下來我主要講一下自己在學習windows核心編程中對于臨界區線程同步方式的使用。

臨界區線程同步在windows核心編程中被稱為關鍵段線程同步,以下統稱關鍵段關鍵段是一小段代碼,它在執行之前需要獨占對一些資源的訪問權。缺點:能且只能用在一個進程中的多線程同步??赡芟萑胨梨i,因為我們無法為進入關鍵段的線程設置最大等待時間。接下來我介紹一些關鍵段線程同步的使用先看一個事例代碼

[html] view plain copyint g_nSum = 0;  CRITICAL_SECTION g_cs;    DWord WINAPI FirstThread(PVOID pvParam)  {    EnterCriticalSection(&g_cs);    g_nSum = 0;    for (int n = 0; n < 10000; ++n)    {      g_nSum += n;    }    LeaveCriticalSection(&g_cs);    return g_nSum;  }    DWORD WINAPI SecondThread(PVOID pvParam)  {    EnterCriticalSection(&g_cs);    g_nSum = 0;    for (int n = 0; n < 10000; ++n)    {      g_nSum += n;    }    LeaveCriticalSection(&g_cs);    return g_nSum;  }  在使用關鍵段(CRITICAL_SECTION)時,只有兩個必要條件:1、想要訪問資源的線程必須知道用來保護資源的CRITICAL_SECTION對象地址。CRITICAL_SECTION對象可以作為全局對象來分配,也可以作為局部對象來分配,或者從堆中動態地分配。2、如何線程在試圖訪問被保護的資源之前,必須對CRITICAL_SECTION結構的內部成員進行初始化。關鍵段線程同步常用函數介紹[html] view plain copy//1、首先我們要分配一個CRITICAL_SECTION對象,并進行初始化(使用關鍵段同步的線程必須調用此函數)  void InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )    //2、當知道線程將不再需要訪問共享資源時,我們應該調用下邊的函數來清理CRITICAL_SECTION結構  void DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection )    //3、在對保護的資源進行訪問之前,必須調用下面的函數  void EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )  //可以對上邊的函數多次調用,表示調用線程被獲準訪問的次數    //4、也可以用下邊的函數代替EnterCriticalSection  BOOL TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )  //通過返回值判斷當前線程是否獲準訪問資源,線程永遠不會進入等待狀態,如果  //返回TRUE表示該線程獲準并正在訪問資源,離開時必須調用LeaveCriticalSection()    //5、在代碼完成對資源的訪問后,必須調用以下函數,釋放訪問權限  void LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection )  //轉載請注明文章來自:http://blog.csdn.net/windows_nt  以上訪問方式(EnterCriticalSection方式)可能會使調用線程切換到等待狀態,這意味著線程必須從用戶模式切換到內核模式,這個切換開銷非常大。為了提高關鍵段的性能,Microsoft把旋轉鎖合并到了關鍵段中。因此,當調用EnterCriticalSection的時候,它會用一個旋轉鎖不斷地循環,嘗試在一段時間內獲得對資源的訪問權,只有當嘗試失敗時,線程才會切換到內核模式并進入等待狀態。

[html] view plain copy//1、為了在使用關鍵段的時候同時使用旋轉鎖,我們必須調用下面的函數來初始化關鍵段  BOOL InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount )  //第二個參數dwSpinCount表示我們希望旋轉鎖循環的次數。    //2、我們也可以調用下面的函數來改變關鍵段的旋轉次數  DWORD SetCriticalSectionSpinCount( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount )  //如果主機只有一個處理器,函數會忽略dwSpinCount參數  

Slim讀/寫鎖

SRWLock允許我們區分那些想要讀取資源的值的線程(讀取者線程)和想要更新資源的值的線程(寫入者線程)。[html] view plain copy//1、首先我們要分配一個SRWLOCK對象并用下邊函數初始化它。  void InitializeSRWLock( __out PSRWLOCK SRWLock )    //2、請求對保護資源的獨占訪問權(寫權限)  void AcquireSRWLockExclusive( __inout PSRWLOCK SRWLock )    //3、完成對資源的更新后,應該解除對資源的鎖定  void ReleaseSRWLockExclusive( __inout PSRWLOCK SRWLock )    //4、對應的讀者線程函數如下  void AcquireSRWLockShared( __inout PSRWLOCK SRWLock )  void ReleaseSRWLockShared( __inout PSRWLOCK SRWLock )  與關鍵段相比,PSRWLOCK缺乏下面兩個特性1、不存在TryEnter(Share/Exclusive)SRWLock之類的函數,如果鎖已經被占用,那么調用會阻塞調用線程2、不能遞歸的獲得PSRWLOCK。也就是說,一個線程不能為了多次寫入資源而多次鎖定資源,如后再多次釋放對資源的鎖定。線程同步性能排序(由高到低)volatile讀取 -->volatile寫入-->Interlocked API(原子方式)-->SRWLock-->關鍵段-->內核對象二、互斥器(Mutexes)的用途和臨界區(critical section)的用途非常相似,如:一個時間內只能夠有一個線程擁有mutex,就好像同一時間內只能夠有一個線程進入同一個critical section一樣。但是mutex通過犧牲速度,提高了靈活性,功能變得更加強大了。雖然mutex和critical section做相同的事情,但它們的運作還是有差別的:1、鎖住一個未被擁有的mutex,比鎖住一個未被擁有的critical section需要花費幾乎100倍的時間。2、mutex可以跨進程使用。critical section則只能在同一個進程中使用。

3、等待一個mutex時,你可以指定“結束等待”的世間長度,但對于critical section則不行。

造成以上差別的主要原因是:mutex是內核對象,critical section非內核對象。

以下是mutex和critical section的相關函數比較:

臨界區互斥器
CRITICAL_SECTIONInitializeCriticalSection()CreateMutex()OpenMutex()
EnterCriticalSection()WaitForSingleObject()WaitForMultipleObjects()MsgWaitForMultipleObjects()
LeaveCriticalSection()ReleaseMutex()
DeleteCriticalSection()CloseHandle()
使用mutex時注意:

在一個適當的程序中,線程絕對不應該在它即將結束前還擁有一個mutex,因為這意味著線程沒有能夠適當地清除其資源。不幸的是,我們并不身處一個完美的世界,有時候,因為某種理由,線程可能沒有在結束前調用ReleaseMutex()。為了解決這個問題,mutex有一個非常重要的特性。這性質在各種同步機制中是獨一無二的,如果線程擁有一個mutex而在結束前沒有調用ReleaseMutex(),mutex不會被摧毀,取而代之的是,該mutex會被視為“未被擁有”以及“未被激發”,而下一個等待中的線程會被以WAIT_ABANDONED_0通知。無論線程是因為ExitThread()而結束,或是因當掉而結束,這種情況都存在。

任何時候只要你想鎖住超過一個以上的同步對象,你就有死鎖的潛在病因。如果總是在相同時間把所有對象都鎖住,問題可去矣。事例如下,存在潛在死鎖的可能:

[html] view plain copyvoid SwapLists(List* list1, List* list2)  {      EnterCriticalSection(list1->critical_sec);      EnterCriticalSection(list2->critical_sec);      //list1,list2數據交換      LeaveCriticalSection(list1->critical_sec);      LeaveCriticalSection(list2->critical_sec);  }  正確的做法:[html] view plain copyvoid SwapLists(List* list1, List* list2)  {      HANDLE arrHandles[2];      arrHandles[0] = list1->hMutex;      arrHandles[1] = list2->hMutex;      WaitForMultipleObjects(2, arrHandles, TRUE, INFINITE);      //list1,list2數據交換      ReleaseMutex(arrHandles[0]);      ReleaseMutex(arrHandles[1]);  }  三、

前邊講過了互斥器線程同步-----windows核心編程-互斥器(Mutexes),這章我來介紹一下信號量(semaphore)線程同步。

理論上說,mutex是semaphore的一種退化。如果你產生一個semaphore并令最大值為1,那就是一個mutex。也因此,mutex又常被稱為binary semaphore。如果某個線程擁有一個binary semaphore,那么就沒有其他線程能夠獲得其擁有權。但是在win32中,這兩種東西的擁有權的意義完全不同,所以它們不能夠交換使用,semaphore不像mutex,它并沒有所謂的“wait abandoned”狀態可以被其他線程偵測到。每當一個鎖定動作成功,semaphore的現值就會減1,你可以使用任何一種wait...()函數來要求鎖定一個semaphore。如果semaphore的現值不為0,wait...()函數會立刻返回,這和mutex很像,當沒有任何線程擁有mutex,wait...()函數會立刻返回。注意,如果鎖定成功,你也不會收到semaphore的擁有權。因為可以有一個以上的線程同時鎖定一個semaphore。所以談semaphore的擁有權并沒有太多實際意義。在semaphore身上并沒有所謂“獨占鎖定”這種事情。也因為沒有所有權的觀念,一個線程可以反復調用wait...()函數以產生新的鎖定。這和mutex絕不相同:擁有mutex的線程不論再調用多少次wait...()函數,也不會被阻塞住。與mutex不同的是,調用ReleaseSemaphore()的那個線程,并不一定就得是調用wait...()的那個線程。任何線程都可以在任何時間調用ReleaseSemaphore(),解除被任何線程鎖定的semaphore。

以下是我對三種同步方式中,常用到的函數的總結。

臨界區互斥器信號量
CRITICAL_SECTIONInitializeCriticalSection()CreateMutex()OpenMutex()CreateSemaphore
EnterCriticalSection()WaitForSingleObject()WaitForMultipleObjects()MsgWaitForMultipleObjects()WaitForSingleObject()WaitForMultipleObjects()MsgWaitForMultipleObjects()...
LeaveCriticalSection()ReleaseMutex()ReleaseSemaphore()
DeleteCriticalSection()CloseHandle()CloseHandle()

事件線程同步----- window核心編程-內核對象線程同步

四、

上一章講了關鍵字(臨界區)線程同步,使用關鍵字線程同步,我們很容易陷入死鎖的情形,這是因為我們無法為進入關鍵段指定一個最長等待時間。

本章將討論如何使用內核對象來對線程同步。我們也將看到,與用戶模式下的同步機制(關鍵段同步)相比,內核對象的用途要廣泛的多。實際上,內核對象唯一的缺點就是它們的性能。內核對象包括進程、線程以及作業,幾乎所有這些內核對象都可以用來進行同步。對線程同步來書,這些內核對象中的每一種要么處于觸發狀態,要么處于未觸發狀態。Microsoft為每種對象創建了一些規則,規定如何在這兩種狀態之間進行轉換。例如,進程內核對象在創建的時候總是處于未觸發狀態。當進程終止的時候,操作系統會自動使進程內核對象變成觸發狀態。當進程內核對象被觸發后,它將永遠保持這種狀態,再也不會變回到未觸發狀態。在進程內核對象的內部有一個布爾變量,當系統創建內核對象的時候會把這個變量的值初始化為false(未觸發)。當進程終止的時候,操作系統會自動把相應的內核對象中的這個布爾值設為true,表示該對象已經被觸發。

下邊講一些內核同步中用到的函數。等該函數使一個線程自愿進入等待狀態,直到指定的內核對象被觸發為止。DWORD waitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);//hObject:內核對象句柄//dwMilliseconds等待時間ms為單位,INFINITE為一直等待,只到內核對象被觸發為止。DWORD WaitForMultipleObjects( DWORD nCount, CONST HANDLE *lpHandles, BOOL bWaitAll, DWORD dwMilliseconds );//waitForSingleObject和WaitForMultipleObjects相似,唯一的不同之處在于它允許調用線程同時檢查多個內核對象的觸發狀態

/*函數的返回值告訴調用方函數為什么它得以繼續運行。如果給bWaitAll傳的是FALSE,那么只要任何一個對象被觸發,函數就會立即返回。這時的返回值是WAIT_OBJECT_0和(WAIT_OBJECT_0+dwCount-1)之間的任何一個值。換句話說,如果返回值既不是WAIT_TIMEOUT,也不是WAIT_FAILED,那么我們應該把返回值減去WAIT_OBJECT_0。得到的數值是我們在第二個參數中傳的句柄數組的一個索引,用來告訴我們被觸發的是那個對象。*/

//下面的事例代碼可以更清晰的對此進行解釋[html] view plain copyHANDLE h[3];//我的博客:<a href="http://blog.csdn.net/windows_nt">http://blog.csdn.net/windows_nt</a>  h[0] = hPRocess1;  h[1] = hProcess2;  h[2] = hProcess3;  DWORD dw = WaitForMultipleObjects(3, h, FALSE, 5000);  switch(dw)  {  case WAIT_FAILED:      //Bad call to function (invalid handle)      break;  case WAIT_TIMEOUT:      //None of the objects became signaled within 5000 milliseconds      break;  case WAIT_OBJECT_0 + 0:      //h[0] signaled, hProcess1 terminated      break;  case WAIT_OBJECT_0 + 1:      //h[1] signaled, hProcess2 terminated      break;  case WAIT_OBJECT_0 + 2:      //h[2] signaled, hProcess3 terminated      break;  }  

2、事件內核對象

//事件包含一個使用計數(這一點和所有其他內核對象一樣),一個用來表示事件是自動重置事件還是手動重置事件的布爾值,以及另一個用來表示事件有沒有被觸發的布爾值。//有兩種不同類型的事件對象:手動重置事件和自動重置事件。當一個手動重置事件被觸發的時候,正在等待該事件的所有線程都將變成可調度狀態,而當一個自動重置事件被觸發的時候,只有一個正在等待該事件的線程會變成可調用狀態。//創建一個事件內核對象HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, //安全屬性BOOL bManualReset, //自動重置/手動重置BOOL bInitialState, //是否觸發

LPCSTR lpName );//事件內核對象的名字,可以為空

//新版本

HANDLE CreateEventEx(LPSECURITY_ATTRIBUTES psa, //安全屬性PCTSTR pszName, //名字DWORD dwFlags, //是否觸發

DWORD dwDesiredaccess)

//dwDesiredAccess:允許我們指定在創建事件時返回的句柄對事件有何種訪問權限。這是一種創建事件句柄的新方法,它可以減少權限,相比較而言,CreateEvent()總是被授予全部權限。但CreateEventEx()更有用的地方在于它允許我們以減少權限的方式來打開一個已經存在的事件,而CreateEvent()總是要求全部權限。

//下邊這個例子展示了如何使用事件內核對象來對線程進行同步。[html] view plain copy//Create a global handle to a manual-reset, nonsignaled event.  HANDLE g_hEvent;  int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,                        LPSTR lpCmdLine, int nShowCmd )  {      //Create the manual-reset, nonsignaled event      g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);      //Spawn 3 new threads      HANDLE hThread[3];      DWORD dwThread;      hThread[0] = _beginthread(NULL, 0, wordCount, NULL, 0, &dwThread);      hThread[1] = _beginthread(NULL, 0, SpellCheck, NULL, 0, &dwThread);      hThread[2] = _beginthread(NULL, 0, GrammarCheck, NULL, 0, &dwThread);          OpenFileAndReadContentsIntoMemory(...);      //allow all 3 threads to access the memory      SetEvent(g_hEvent);  }      DWORD WINAPI wordCount(PVOID pvParam)  {      //Wait until the file's data is in memory      waitForSingleObject(g_hEvent, INFINITE);      //access the memory block.      return 0;  }      DWORD WINAPI SpellCheck(PVOID pvParam)  {      //Wait until the file's data is in memory      waitForSingleObject(g_hEvent, INFINITE);      //access the memory block.      return 0;  }      DWORD WINAPI GrammarCheck(PVOID pvParam)  {      //Wait until the file's data is in memory      waitForSingleObject(g_hEvent, INFINITE);      //access the memory block.      return 0;  }  

下邊是我自己寫的一個事例片段,很簡單

[html] view plain copyCString strName = _T("");    UINT CBcgTestDlg::ThreadWorkFunc(LPVOID lPvoid)  {            for (int n = 0; n < 10000; n++)      {          strName = _T("http://blog.csdn.net/windows_nt");          strName = strName + _T("/n");          TRACE(strName);      }            return 0;  }    void CBcgTestDlg::OnOK()   {      CWinThread* pThread = NULL;        for (int n = 0; n < 10000; ++n)      {          if (pThread)          {              WaitForSingleObject(pThread->m_hThread, INFINITE);              delete pThread;          }                    pThread = AfxBeginThread(ThreadWorkFunc, NULL, 0, CREATE_SUSPENDED, NULL);          if (pThread)          {              pThread->m_bAutoDelete = FALSE;              pThread->ResumeThread();          }      }  }  注意線程函數可以為類函數,但必須是靜態函數


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩欧美国产骚| 亚洲小视频在线| 亚洲成人激情在线观看| 成人免费福利在线| 国产欧美日韩中文字幕在线| 91国偷自产一区二区三区的观看方式| 久久影视三级福利片| 国产精品视频一区二区高潮| 欧美成年人在线观看| 国产香蕉一区二区三区在线视频| 97色在线视频| 久久久精品国产网站| 久久久精品999| 日韩免费观看av| 欧美成人性生活| 国产精品一区二区久久国产| 午夜精品一区二区三区视频免费看| 97在线视频免费看| 美日韩精品免费视频| 亚洲福利在线观看| 亚洲成人a**站| 中文字幕av一区中文字幕天堂| 午夜精品三级视频福利| 欧美自拍视频在线| 精品亚洲精品福利线在观看| 精品视频久久久久久久| 2020欧美日韩在线视频| 伊人久久久久久久久久久久久| 欧美激情精品久久久久久蜜臀| 欧美亚州一区二区三区| 国产在线拍偷自揄拍精品| 亚洲人成网站在线播| 欧美国产视频一区二区| 久久理论片午夜琪琪电影网| 欧美放荡办公室videos4k| 精品国产一区av| 国产福利视频一区| 国产在线播放91| 日韩美女免费观看| 亚洲第一二三四五区| 久久亚洲一区二区三区四区五区高| 亚洲天堂成人在线视频| 亚洲国产精品999| 亚洲视频专区在线| 国产精品美女久久久久av超清| 亚洲午夜久久久久久久| 岛国精品视频在线播放| 久久精品青青大伊人av| 亚洲精品久久在线| 黄色成人在线播放| 国产精品一区二区久久久久| 亚洲变态欧美另类捆绑| 亚洲理论在线a中文字幕| 欧美裸体xxxxx| 精品色蜜蜜精品视频在线观看| 国产亚洲精品美女久久久| 日本精品视频在线播放| 成人黄色中文字幕| 热门国产精品亚洲第一区在线| 精品小视频在线| 97在线日本国产| 亚洲国产精品成人va在线观看| 欧美韩日一区二区| 国产精品视频专区| 欧美亚洲一区在线| 欧美日韩精品二区| 亚洲国产成人爱av在线播放| 国产一区二区三区在线观看视频| 91在线免费观看网站| 欧洲成人在线观看| 国产精品天天狠天天看| 国产精品白嫩美女在线观看| 亚洲国产精品推荐| 国产精品精品国产| 裸体女人亚洲精品一区| 欧美综合在线第二页| 亚洲xxxx18| 日韩视频一区在线| 欧美午夜激情在线| 国产高清在线不卡| 国产亚洲成av人片在线观看桃| 色诱女教师一区二区三区| 色香阁99久久精品久久久| 亚洲一区二区三区在线免费观看| 亚洲日本欧美日韩高观看| 亚洲精品成人久久电影| 亚洲人成在线免费观看| 大桥未久av一区二区三区| 懂色av中文一区二区三区天美| 欧美老女人在线视频| 97人人做人人爱| 在线观看国产成人av片| 亚洲精品中文字| 欧美激情一级精品国产| 欧美亚洲视频在线看网址| 亚洲综合精品伊人久久| 38少妇精品导航| 日韩电影中文字幕av| 国产亚洲激情视频在线| 精品国产自在精品国产浪潮| 亚洲福利精品在线| 国产91精品久久久| 欧美大片免费观看在线观看网站推荐| 欧美精品免费看| 欧美大片欧美激情性色a∨久久| 国产精品视频网站| 成人免费xxxxx在线观看| 久久免费高清视频| 一区二区日韩精品| 国产成人一区二区三区小说| 91高清视频免费观看| 日韩精品免费在线视频观看| 国产成人一区二区三区电影| 亚洲视频电影图片偷拍一区| 夜夜嗨av色一区二区不卡| 欧美怡红院视频一区二区三区| 日韩经典一区二区三区| 欧美激情精品久久久| 午夜精品久久久久久久久久久久| 亚洲香蕉在线观看| 亚洲国产成人久久综合| 精品中文视频在线| 成人在线视频网| 国产精品成人一区| 久久天天躁狠狠躁夜夜躁2014| 欧美激情视频网| 日韩免费电影在线观看| 久久精品国产96久久久香蕉| 国产偷国产偷亚洲清高网站| 欧美午夜精品久久久久久久| 一区二区欧美久久| 欧美日韩爱爱视频| 久久久噜久噜久久综合| 日韩黄色在线免费观看| 成人免费大片黄在线播放| 91精品国产91久久久久久不卡| 久久影院在线观看| 国产综合在线视频| 欧美性猛xxx| 久久综合国产精品台湾中文娱乐网| 久久91亚洲人成电影网站| 亚洲天堂av综合网| 久久久人成影片一区二区三区| 欧美亚洲在线视频| 精品在线欧美视频| 中文字幕欧美亚洲| 欧美激情一区二区三级高清视频| 97精品一区二区视频在线观看| 欧美精品久久一区二区| 久久全国免费视频| 国产精品入口夜色视频大尺度| 2019中文字幕在线观看| 国产精品露脸自拍| 欧美美女15p| 亚洲欧美日韩图片| 久久精品亚洲热| 成人国产精品免费视频| 亚洲人成绝费网站色www| 国产一区二区三区视频在线观看| 亚洲欧美日韩精品久久奇米色影视| 国产欧美一区二区三区视频| 黑人巨大精品欧美一区二区一视频| 日韩欧美中文第一页| 久久的精品视频|