• <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>

            cc

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

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

            該教程說明各種線程活動(dòng):

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

            教程

            該教程包含下列示例:

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

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

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

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

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

            // 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 對(duì)象,此對(duì)象使程序能夠知道線程池何時(shí)運(yùn)行完所有的工作項(xiàng)。接著,嘗試向線程池添加一個(gè)線程。如果添加成功,則添加其余的線程(本例中為 4 個(gè))。然后線程池將工作項(xiàng)放入可用線程中。調(diào)用 eventX 上的 WaitOne 方法,這會(huì)使程序的其余部分等待,直到用 eventX.Set 方法觸發(fā)事件為止。最后,程序打印出線程上的負(fù)載(實(shí)際執(zhí)行某一特定工作項(xiàng)的線程)。

            // 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;
               }
            }

            輸出示例

            注意???下列輸出隨計(jì)算機(jī)的不同而不同。
            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 對(duì)象

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

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

            // 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ái)計(jì)算機(jī)上以及每次運(yùn)行時(shí)均各不相同。運(yùn)行此示例的計(jì)算機(jī)的速度及其操作系統(tǒng)都能影響輸出的順序。在多線程環(huán)境中,事件可能并不按預(yù)期的順序發(fā)生。
            posted on 2006-12-07 15:00 醒目西西 閱讀(193) 評(píng)論(0)  編輯 收藏 引用

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


            久久精品国产亚洲AV蜜臀色欲| 日本一区精品久久久久影院| 久久91综合国产91久久精品| 久久精品国产精品亚洲精品 | 久久久久亚洲AV无码专区桃色| 久久精品国产亚洲AV嫖农村妇女| 亚洲av伊人久久综合密臀性色| 大香伊人久久精品一区二区| 久久婷婷五月综合97色直播| 久久亚洲精品无码VA大香大香| 精品国产乱码久久久久久呢| 综合久久一区二区三区 | 性高朝久久久久久久久久| 人人狠狠综合久久亚洲| 久久天天婷婷五月俺也去| 久久精品国产亚洲AV影院| 久久久精品国产sm调教网站| AV狠狠色丁香婷婷综合久久| 91精品国产综合久久四虎久久无码一级| 青青草国产成人久久91网| 日批日出水久久亚洲精品tv| 久久久精品久久久久影院| 久久婷婷五月综合色高清| 中文字幕成人精品久久不卡| 欧美国产精品久久高清| 亚洲va久久久噜噜噜久久| 99久久伊人精品综合观看| 狠狠色丁香久久婷婷综合_中| 久久久婷婷五月亚洲97号色| 97精品伊人久久久大香线蕉| 九九精品久久久久久噜噜| 久久精品国产亚洲av麻豆色欲| 国产精品青草久久久久福利99| 精品久久久久久久久免费影院| 国产精品久久久久久福利漫画| 久久精品国产亚洲Aⅴ香蕉| 久久久久久久久无码精品亚洲日韩 | 久久精品国产亚洲av日韩| 久久久久国产视频电影| 久久w5ww成w人免费| 亚洲国产成人精品女人久久久 |