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

cc

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  38 隨筆 :: 14 文章 :: 21 評論 :: 0 Trackbacks

線程處理的優(yōu)點是可以創(chuàng)建使用多個執(zhí)行線程的應(yīng)用程序。例如,某一進(jìn)程可以具有管理與用戶交互的用戶界面線程,以及在用戶界面線程等待用戶輸入時執(zhí)行其他任務(wù)的輔助線程。

該教程說明各種線程活動:

  • 創(chuàng)建和執(zhí)行線程
  • 線程同步
  • 線程間交互
  • 使用線程池
  • 使用 mutex 對象保護(hù)共享資源

教程

該教程包含下列示例:

示例 1:創(chuàng)建線程、啟動線程和線程間交互

本示例說明如何創(chuàng)建和啟動線程,并顯示了同時在同一進(jìn)程內(nèi)運行的兩個線程間的交互。請注意,不必停止或釋放線程。這由 .NET Framework 公共語言運行庫自動完成。

程序從創(chuàng)建 Alpha 類型的對象 (oAlpha) 和引用 Alpha 類的 Beta 方法的線程 (oThread) 開始。然后啟動該線程。線程的 IsAlive 屬性允許程序等待,直到線程被初始化(被創(chuàng)建、被分配等)為止。主線程通過 Thread 訪問,而 Sleep 方法通知線程放棄其時間片并在一定毫秒數(shù)期間停止執(zhí)行。然后 oThread 被停止和聯(lián)接。聯(lián)接一個線程將使主線程等待它死亡或等待它在指定的時間后過期。最后,程序嘗試重新啟動 oThread,但由于線程無法在停止(中止)后重新啟動而告失敗。有關(guān)臨時停止執(zhí)行的信息,請參見掛起線程執(zhí)行。

// StopJoin.cs
using System;
using System.Threading;

public class Alpha
{

   // This method that will be called when the thread is started
   public void Beta()
   {
      while (true)
      {
         Console.WriteLine(“Alpha.Beta is running in its own thread.“);
      }
   }
};

public class Simple
{
   public static int Main()
   {
      Console.WriteLine(“Thread Start/Stop/Join Sample“);
      
      Alpha oAlpha = new Alpha();

      // Create the thread object, passing in the Alpha.Beta method
      // via a ThreadStart delegate. This does not start the thread.
      Thread oThread = new Thread(new ThreadStart(oAlpha.Beta));

      // Start the thread
      oThread.Start();

      // Spin for a while waiting for the started thread to become
      // alive:
      while (!oThread.IsAlive);
      
      // Put the Main thread to sleep for 1 millisecond to allow oThread
      // to do some work:
      Thread.Sleep(1);
      
      // Request that oThread be stopped
      oThread.Abort();
      
      // Wait until oThread finishes. Join also has overloads
      // that take a millisecond interval or a TimeSpan object.
      oThread.Join();
      
      Console.WriteLine();
      Console.WriteLine(“Alpha.Beta has finished“);
      
      try 
      {
         Console.WriteLine(“Try to restart the Alpha.Beta thread“);
         oThread.Start();
      }
      catch (ThreadStateException) 
      {
         Console.Write(“ThreadStateException trying to restart Alpha.Beta. “);
         Console.WriteLine(“Expected since aborted threads cannot be restarted.“);
      }
      return 0;
   }
}

輸出示例

Thread Start/Stop/Join Sample
Alpha.Beta is running in its own thread.
Alpha.Beta is running in its own thread.
Alpha.Beta is running in its own thread.
...
...
Alpha.Beta has finished
Try to restart the Alpha.Beta thread
ThreadStateException trying to restart Alpha.Beta. Expected since aborted threads cannot be restarted.

示例 2:同步兩個線程:制造者和使用者

下面的示例顯示如何使用 C# lock 關(guān)鍵字和 Monitor 對象的 Pulse 方法完成同步。Pulse 方法通知等待隊列中的線程對象的狀態(tài)已更改。(有關(guān)脈沖的更多詳細(xì)信息,請參見 Monitor.Pulse 方法)。

本示例創(chuàng)建一個 Cell 對象,它具有兩個方法:ReadFromCellWriteToCell。從 CellProdCellCons 類創(chuàng)建另外兩個對象;這兩個對象均具有調(diào)用 ReadFromCellWriteToCellThreadRun 方法。通過等待依次到達(dá)的來自 Monitor 對象的“脈沖”即可完成同步。也就是說,首先產(chǎn)生一個項(此時使用者等待脈沖),然后發(fā)生一個脈沖,接著使用者使用所產(chǎn)生的項(此時制造者等待脈沖),依此類推。

// MonitorSample.cs
// This example shows use of the following methods of the C# lock keyword
// and the Monitor class 
// in threads:
//      Monitor.Pulse(Object)
//      Monitor.Wait(Object)
using System;
using System.Threading;

public class MonitorSample
{
   public static void Main(String[] args)
   {
      int result = 0;   // Result initialized to say there is no error
      Cell cell = new Cell( );

      CellProd prod = new CellProd(cell, 20);  // Use cell for storage, 
                                               // produce 20 items
      CellCons cons = new CellCons(cell, 20);  // Use cell for storage, 
                                               // consume 20 items

      Thread producer = new Thread(new ThreadStart(prod.ThreadRun));
      Thread consumer = new Thread(new ThreadStart(cons.ThreadRun));
      // Threads producer and consumer have been created, 
      // but not started at this point.

      try
      {
         producer.Start( );
         consumer.Start( );

         producer.Join( );   // Join both threads with no timeout
                             // Run both until done.
         consumer.Join( );  
      // threads producer and consumer have finished at this point.
      }
      catch (ThreadStateException e)
      {
         Console.WriteLine(e);  // Display text of exception
         result = 1;            // Result says there was an error
      }
      catch (ThreadInterruptedException e)
      {
         Console.WriteLine(e);  // This exception means that the thread
                                // was interrupted during a Wait
         result = 1;            // Result says there was an error
      }
      // Even though Main returns void, this provides a return code to 
      // the parent process.
      Environment.ExitCode = result;
   }
}

public class CellProd
{
   Cell cell;         // Field to hold cell object to be used
   int quantity = 1;  // Field for how many items to produce in cell

   public CellProd(Cell box, int request)
   {
      cell = box;          // Pass in what cell object to be used
      quantity = request;  // Pass in how many items to produce in cell
   }
   public void ThreadRun( )
   {
      for(int looper=1; looper<=quantity; looper++)
         cell.WriteToCell(looper);  // “producing“
   }
}

public class CellCons
{
   Cell cell;         // Field to hold cell object to be used
   int quantity = 1;  // Field for how many items to consume from cell

   public CellCons(Cell box, int request)
   {
      cell = box;          // Pass in what cell object to be used
      quantity = request;  // Pass in how many items to consume from cell
   }
   public void ThreadRun( )
   {
      int valReturned;
      for(int looper=1; looper<=quantity; looper++)
      // Consume the result by placing it in valReturned.
         valReturned=cell.ReadFromCell( );
   }
}

public class Cell
{
   int cellContents;         // Cell contents
   bool readerFlag = false;  // State flag
   public int ReadFromCell( )
   {
      lock(this)   // Enter synchronization block
      {
         if (!readerFlag)
         {            // Wait until Cell.WriteToCell is done producing
            try
            {
               // Waits for the Monitor.Pulse in WriteToCell
               Monitor.Wait(this);
            }
            catch (SynchronizationLockException e)
            {
               Console.WriteLine(e);
            }
            catch (ThreadInterruptedException e)
            {
               Console.WriteLine(e);
            }
         }
         Console.WriteLine(“Consume: {0}“,cellContents);
         readerFlag = false;    // Reset the state flag to say consuming
                                // is done.
         Monitor.Pulse(this);   // Pulse tells Cell.WriteToCell that
                                // Cell.ReadFromCell is done.
      }   // Exit synchronization block
      return cellContents;
   }
   
   public void WriteToCell(int n)
   {
      lock(this)  // Enter synchronization block
      {
         if (readerFlag)
         {      // Wait until Cell.ReadFromCell is done consuming.
            try
            {
               Monitor.Wait(this);   // Wait for the Monitor.Pulse in
                                     // ReadFromCell
            }
            catch (SynchronizationLockException e)
            {
               Console.WriteLine(e);
            }
            catch (ThreadInterruptedException e)
            {
               Console.WriteLine(e);
            }
         }
         cellContents = n;
         Console.WriteLine(“Produce: {0}“,cellContents);
         readerFlag = true;    // Reset the state flag to say producing
                               // is done
         Monitor.Pulse(this);  // Pulse tells Cell.ReadFromCell that 
                               // Cell.WriteToCell is done.
      }   // Exit synchronization block
   }
}

輸出示例

Produce: 1
Consume: 1
Produce: 2
Consume: 2
Produce: 3
Consume: 3
...
...
Produce: 20
Consume: 20

示例 3:使用線程池

以下示例顯示如何使用線程池。首先創(chuàng)建 ManualResetEvent 對象,此對象使程序能夠知道線程池何時運行完所有的工作項。接著,嘗試向線程池添加一個線程。如果添加成功,則添加其余的線程(本例中為 4 個)。然后線程池將工作項放入可用線程中。調(diào)用 eventX 上的 WaitOne 方法,這會使程序的其余部分等待,直到用 eventX.Set 方法觸發(fā)事件為止。最后,程序打印出線程上的負(fù)載(實際執(zhí)行某一特定工作項的線程)。

// SimplePool.cs
// Simple thread pool example
using System;
using System.Collections;
using System.Threading;

// Useful way to store info that can be passed as a state on a work item
public class SomeState
{
   public int Cookie;
   public SomeState(int iCookie)
   {
      Cookie = iCookie;
   }
}

public class Alpha
{
   public Hashtable HashCount;
   public ManualResetEvent eventX;
   public static int iCount = 0;
   public static int iMaxCount = 0;
   public Alpha(int MaxCount) 
   {
      HashCount = new Hashtable(MaxCount);
      iMaxCount = MaxCount;
   }

   // Beta is the method that will be called when the work item is
   // serviced on the thread pool.
   // That means this method will be called when the thread pool has
   // an available thread for the work item.
   public void Beta(Object state)
   {
      // Write out the hashcode and cookie for the current thread
      Console.WriteLine(“ {0} {1} :“, Thread.CurrentThread.GetHashCode(),
         ((SomeState)state).Cookie);
      // The lock keyword allows thread-safe modification
      // of variables accessible across multiple threads.
      Console.WriteLine(
         “HashCount.Count=={0}, Thread.CurrentThread.GetHashCode()=={1}“,
         HashCount.Count, 
         Thread.CurrentThread.GetHashCode());
      lock (HashCount) 
      {
         if (!HashCount.ContainsKey(Thread.CurrentThread.GetHashCode()))
            HashCount.Add (Thread.CurrentThread.GetHashCode(), 0);
         HashCount[Thread.CurrentThread.GetHashCode()] = 
            ((int)HashCount[Thread.CurrentThread.GetHashCode()])+1;
      }

      // Do some busy work.
      // Note: Depending on the speed of your machine, if you 
      // increase this number, the dispersement of the thread
      // loads should be wider.
      int iX  = 2000;
      Thread.Sleep(iX);
      // The Interlocked.Increment method allows thread-safe modification
      // of variables accessible across multiple threads.
      Interlocked.Increment(ref iCount);
      if (iCount == iMaxCount)
      {
         Console.WriteLine();
         Console.WriteLine(“Setting eventX “);
         eventX.Set();
      }
   }
}

public class SimplePool
{
   public static int Main(string[] args)
   {
      Console.WriteLine(“Thread Pool Sample:“);
      bool W2K = false;
      int MaxCount = 10;  // Allow a total of 10 threads in the pool
      // Mark the event as unsignaled.
      ManualResetEvent eventX = new ManualResetEvent(false);
      Console.WriteLine(“Queuing {0} items to Thread Pool“, MaxCount);
      Alpha oAlpha = new Alpha(MaxCount);  // Create the work items.
      // Make sure the work items have a reference to the signaling event.
      oAlpha.eventX = eventX;
      Console.WriteLine(“Queue to Thread Pool 0“);
      try
      {
         // Queue the work items, which has the added effect of checking
         // which OS is running.
         ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta),
            new SomeState(0));
         W2K = true;
      }
      catch (NotSupportedException)
      {
         Console.WriteLine(“These API‘s may fail when called on a non-Windows 2000 system.“);
         W2K = false;
      }
      if (W2K)  // If running on an OS which supports the ThreadPool methods.
      {
         for (int iItem=1;iItem < MaxCount;iItem++)
         {
            // Queue the work items:
            Console.WriteLine(“Queue to Thread Pool {0}“, iItem);
            ThreadPool.QueueUserWorkItem(new WaitCallback(oAlpha.Beta),new SomeState(iItem));
         }
         Console.WriteLine(“Waiting for Thread Pool to drain“);
         // The call to exventX.WaitOne sets the event to wait until
         // eventX.Set() occurs.
         // (See oAlpha.Beta).
         // Wait until event is fired, meaning eventX.Set() was called:
         eventX.WaitOne(Timeout.Infinite,true);
         // The WaitOne won‘t return until the event has been signaled.
         Console.WriteLine(“Thread Pool has been drained (Event fired)“);
         Console.WriteLine();
         Console.WriteLine(“Load across threads“);
         foreach(object o in oAlpha.HashCount.Keys)
            Console.WriteLine(“{0} {1}“, o, oAlpha.HashCount[o]);
      }
      return 0;
   }
}

輸出示例

注意???下列輸出隨計算機的不同而不同。
Thread Pool Sample:
Queuing 10 items to Thread Pool
Queue to Thread Pool 0
Queue to Thread Pool 1
...
...
Queue to Thread Pool 9
Waiting for Thread Pool to drain
 98 0 :
HashCount.Count==0, Thread.CurrentThread.GetHashCode()==98
 100 1 :
HashCount.Count==1, Thread.CurrentThread.GetHashCode()==100
 98 2 :
...
...
Setting eventX
Thread Pool has been drained (Event fired)

Load across threads
101 2
100 3
98 4
102 1

示例 4:使用 Mutex 對象

可以使用 mutex 對象保護(hù)共享資源不被多個線程或進(jìn)程同時訪問。mutex 對象的狀態(tài)或者設(shè)置為終止(當(dāng)它不屬于任何線程時),或者設(shè)置為非終止(當(dāng)它屬于某個線程時)。同時只能有一個線程擁有一個 mutex 對象。例如,為了防止兩個線程同時寫入共享內(nèi)存,每個線程在執(zhí)行訪問該共享內(nèi)存的代碼之前等待 mutex 對象的所屬權(quán)。寫入共享內(nèi)存后,線程將釋放該 mutex 對象。

此示例闡釋如何在處理線程過程中使用 Mutex 類、AutoResetEvent 類和 WaitHandle 類。它還闡釋在處理 mutex 對象過程中所用的方法。

// Mutex.cs
// Mutex object example
using System;
using System.Threading;

public class MutexSample
{
   static Mutex gM1;
   static Mutex gM2;
   const int ITERS = 100;
   static AutoResetEvent Event1 = new AutoResetEvent(false);
   static AutoResetEvent Event2 = new AutoResetEvent(false);
   static AutoResetEvent Event3 = new AutoResetEvent(false);
   static AutoResetEvent Event4 = new AutoResetEvent(false);
   
   public static void Main(String[] args)
   {
      Console.WriteLine(“Mutex Sample ...“);
      // Create Mutex initialOwned, with name of “MyMutex“.
      gM1 = new Mutex(true,“MyMutex“);
      // Create Mutex initialOwned, with no name.
      gM2 = new Mutex(true);
      Console.WriteLine(“ - Main Owns gM1 and gM2“);

      AutoResetEvent[] evs = new AutoResetEvent[4];
      evs[0] = Event1;    // Event for t1
      evs[1] = Event2;    // Event for t2
      evs[2] = Event3;    // Event for t3
      evs[3] = Event4;    // Event for t4

      MutexSample tm = new MutexSample( );
      Thread t1 = new Thread(new ThreadStart(tm.t1Start));
      Thread t2 = new Thread(new ThreadStart(tm.t2Start));
      Thread t3 = new Thread(new ThreadStart(tm.t3Start));
      Thread t4 = new Thread(new ThreadStart(tm.t4Start));
      t1.Start( );   // Does Mutex.WaitAll(Mutex[] of gM1 and gM2)
      t2.Start( );   // Does Mutex.WaitOne(Mutex gM1)
      t3.Start( );   // Does Mutex.WaitAny(Mutex[] of gM1 and gM2)
      t4.Start( );   // Does Mutex.WaitOne(Mutex gM2)

      Thread.Sleep(2000);
      Console.WriteLine(“ - Main releases gM1“);
      gM1.ReleaseMutex( );  // t2 and t3 will end and signal

      Thread.Sleep(1000);
      Console.WriteLine(“ - Main releases gM2“);
      gM2.ReleaseMutex( );  // t1 and t4 will end and signal

      // Waiting until all four threads signal that they are done.
      WaitHandle.WaitAll(evs); 
      Console.WriteLine(“... Mutex Sample“);
   }

   public void t1Start( )
   {
      Console.WriteLine(“t1Start started,  Mutex.WaitAll(Mutex[])“);
      Mutex[] gMs = new Mutex[2];
      gMs[0] = gM1;  // Create and load an array of Mutex for WaitAll call
      gMs[1] = gM2;
      Mutex.WaitAll(gMs);  // Waits until both gM1 and gM2 are released
      Thread.Sleep(2000);
      Console.WriteLine(“t1Start finished, Mutex.WaitAll(Mutex[]) satisfied“);
      Event1.Set( );      // AutoResetEvent.Set() flagging method is done
   }

   public void t2Start( )
   {
      Console.WriteLine(“t2Start started,  gM1.WaitOne( )“);
      gM1.WaitOne( );    // Waits until Mutex gM1 is released
      Console.WriteLine(“t2Start finished, gM1.WaitOne( ) satisfied“);
      Event2.Set( );     // AutoResetEvent.Set() flagging method is done
   }

   public void t3Start( )
   {
      Console.WriteLine(“t3Start started,  Mutex.WaitAny(Mutex[])“);
      Mutex[] gMs = new Mutex[2];
      gMs[0] = gM1;  // Create and load an array of Mutex for WaitAny call
      gMs[1] = gM2;
      Mutex.WaitAny(gMs);  // Waits until either Mutex is released
      Console.WriteLine(“t3Start finished, Mutex.WaitAny(Mutex[])“);
      Event3.Set( );       // AutoResetEvent.Set() flagging method is done
   }

   public void t4Start( )
   {
      Console.WriteLine(“t4Start started,  gM2.WaitOne( )“);
      gM2.WaitOne( );   // Waits until Mutex gM2 is released
      Console.WriteLine(“t4Start finished, gM2.WaitOne( )“);
      Event4.Set( );    // AutoResetEvent.Set() flagging method is done
   }
}

示例輸出

Mutex Sample ...
 - Main Owns gM1 and gM2
t1Start started,  Mutex.WaitAll(Mutex[])
t2Start started,  gM1.WaitOne( )
t3Start started,  Mutex.WaitAny(Mutex[])
t4Start started,  gM2.WaitOne( )
 - Main releases gM1
t2Start finished, gM1.WaitOne( ) satisfied
t3Start finished, Mutex.WaitAny(Mutex[])
 - Main releases gM2
t1Start finished, Mutex.WaitAll(Mutex[]) satisfied
t4Start finished, gM2.WaitOne( )
... Mutex Sample
注意???此示例的輸出可能在每臺計算機上以及每次運行時均各不相同。運行此示例的計算機的速度及其操作系統(tǒng)都能影響輸出的順序。在多線程環(huán)境中,事件可能并不按預(yù)期的順序發(fā)生。
posted on 2006-12-07 15:00 醒目西西 閱讀(207) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲高清视频在线观看| 久久亚洲精品一区二区| 亚洲人成久久| 欧美日韩一区二区三区免费看| 一区二区三区四区国产精品| 一区二区三区|亚洲午夜| 国产精品毛片a∨一区二区三区|国| 亚洲欧美综合国产精品一区| 欧美在线观看一二区| 在线观看精品| 国产日产欧产精品推荐色 | 亚洲视频在线一区观看| 国产精品日韩精品欧美在线| 久久成人精品| 欧美第一黄网免费网站| 亚洲午夜精品在线| 久久国产免费| 一区二区精品| 久久狠狠亚洲综合| 一本色道久久综合亚洲精品高清| 亚洲在线网站| 亚洲精品乱码久久久久久蜜桃91| 99视频一区| 好吊日精品视频| 亚洲精品日韩一| 红桃视频国产一区| 亚洲视屏在线播放| 亚洲国产一区在线观看| 亚洲一区欧美激情| 亚洲美女av在线播放| 欧美亚洲在线| 亚洲一区二区三区777| 久久精品在线| 午夜在线a亚洲v天堂网2018| 裸体素人女欧美日韩| 欧美在现视频| 欧美午夜在线| 国产亚洲欧洲一区高清在线观看| 欧美国产一区二区三区激情无套| 国产精品专区第二| 一区二区高清| 一本久久a久久免费精品不卡| 久久精品一本久久99精品| 亚洲专区欧美专区| 欧美精品在线观看一区二区| 美女视频一区免费观看| 国产欧美日韩一级| av成人动漫| 正在播放亚洲| 欧美日韩国产高清视频| 亚洲第一中文字幕| 在线视频成人| 久久一区二区三区国产精品| 久久久99爱| 国产色产综合产在线视频| 亚洲午夜电影在线观看| 亚洲午夜久久久久久久久电影院 | 亚洲国产成人av好男人在线观看| 欧美一区二区在线观看| 久久av二区| 国产午夜精品在线| 欧美一区二区三区日韩视频| 欧美在线观看视频一区二区| 国产精品久久久久9999| 在线午夜精品自拍| 亚洲欧美日韩综合国产aⅴ| 国产精品初高中精品久久| 99国产成+人+综合+亚洲欧美| 中文一区二区在线观看| 国产精品v日韩精品v欧美精品网站 | 欧美人成网站| 99精品久久| 欧美一区二区三区免费观看视频| 国产精品亚洲美女av网站| 午夜精品久久久久| 美国十次成人| 亚洲伦理自拍| 国产精品毛片va一区二区三区 | 欧美激情在线免费观看| 亚洲精品网站在线播放gif| 亚洲一二三四区| 国产精品永久入口久久久| 久久精品国产精品亚洲精品| 欧美成人a视频| 99精品久久免费看蜜臀剧情介绍| 欧美日韩免费观看一区=区三区| 亚洲精品三级| 久久久久久婷| 一区二区三区偷拍| 国产一区二区精品丝袜| 裸体歌舞表演一区二区| 宅男在线国产精品| 老司机精品久久| 午夜综合激情| 亚洲国产日韩一级| 欧美夜福利tv在线| 亚洲精品免费电影| 国产亚洲视频在线| 欧美精品激情在线| 香蕉久久a毛片| 亚洲精品少妇| 久久这里有精品15一区二区三区| 99re热精品| 精品999日本| 国产免费亚洲高清| 欧美精品色网| 久久久在线视频| 亚洲永久精品大片| 亚洲人成啪啪网站| 免费h精品视频在线播放| 亚洲免费视频中文字幕| 亚洲激情一区| 狠狠久久婷婷| 国产伦精品一区二区三区照片91| 欧美激情一区二区三级高清视频| 欧美在线视频网站| 亚洲午夜日本在线观看| 最新成人av在线| 欧美成人激情视频| 久久久999成人| 欧美一区午夜精品| 亚洲影院色在线观看免费| 亚洲人成艺术| 一色屋精品视频在线看| 国产毛片一区| 国产精品三级久久久久久电影| 欧美xxxx在线观看| 久久综合久久综合久久综合| 西西人体一区二区| 亚洲资源在线观看| 中国亚洲黄色| 一区二区三区 在线观看视| 亚洲黄色一区二区三区| 欧美成人三级在线| 欧美成人黄色小视频| 免费成年人欧美视频| 暖暖成人免费视频| 模特精品在线| 亚洲成人资源| 亚洲欧洲日产国码二区| 亚洲九九精品| 宅男噜噜噜66一区二区66| 一本久久青青| 亚洲精品一区二区三区99| 亚洲激情成人网| 亚洲欧洲精品一区二区| 亚洲精品午夜精品| 亚洲精品国产拍免费91在线| 日韩午夜剧场| 亚洲综合国产| 久久久久欧美精品| 欧美黑人多人双交| 亚洲精品乱码久久久久久日本蜜臀 | 久久夜色精品国产噜噜av| 久久综合给合久久狠狠狠97色69| 噜噜噜在线观看免费视频日韩| 美女免费视频一区| 欧美大片免费久久精品三p| 欧美精品aa| 国产精品一区视频| 伊人成人在线视频| 99视频精品在线| 午夜精品美女久久久久av福利| 久久久精品动漫| 亚洲黄色av一区| 亚洲私人影院| 久久综合精品一区| 欧美日韩国产va另类| 国产精品视频网站| 在线免费日韩片| 亚洲午夜成aⅴ人片| 久久久久久有精品国产| 亚洲精品乱码久久久久久黑人| 在线天堂一区av电影| 久久久亚洲综合| 欧美性大战久久久久久久| 韩日在线一区| 亚洲综合成人婷婷小说| 免费一区视频| 亚洲综合欧美日韩| 另类激情亚洲| 国产精品日韩欧美| 日韩视频一区二区三区在线播放免费观看| 亚洲午夜在线视频| 免费亚洲电影| 欧美一级久久久| 欧美三区在线观看| 最新日韩av| 久久一区二区三区国产精品| 亚洲最新在线视频| 欧美a级大片| 狠狠爱综合网| 久久精品亚洲| 一区二区电影免费观看| 蜜臀va亚洲va欧美va天堂| 国产亚洲精品资源在线26u| 亚洲视频免费看| 91久久精品国产91久久性色tv| 欧美专区日韩专区| 国产精品丝袜xxxxxxx|