<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
1.為了防止一個應用程式控制CPU而導致其他應用程式和作業系統本身永遠被掛起這一可能情況,作業系統不得不使用某種方式將物理計算分割為一些虛擬的程序,並給予每個執行程式一定量的計算能力。此外作業系統必須始終能夠優先存取CPU,並能調整不同程式存取CPU的優先順序。執行緒正式這一慨唸的實現。
2.多執行緒優缺點:
多執行緒優點:可以同時執行多個計算任務,有可能提高計算機的處理能力,使得計算機每秒能執行越來越多的命令
多執行緒缺點:消耗大量的作業系統資源。多個執行緒共用一個處理器將導致作業系統忙於管理這些執行緒,而無法執行程式。
class Program { static void Main(string[] args) { Thread t1 = new Thread(new ThreadStart(PrintNumbers));//無引數的委託,把方法的參照當做引數 t1.Start(); Thread t2 = new Thread(new ParameterizedThreadStart(PrintNumbers));//有引數的委託,把方法的參照當做引數 t2.Start(10); Console.ReadLine(); } static void PrintNumbers() { Console.WriteLine("1.Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine(i); } } //注意:要使用ParameterizedThreadStart,定義的引數必須為object static void PrintNumbers(object count) { Console.WriteLine("2.Starting..."); for (int i = 0; i < Convert.ToInt32(count); i++) { Console.WriteLine(i); } } } }
註釋:
1.我們只需指定在不同執行緒執行的方法名,而C#編譯器會在後臺建立這些物件。
2.要使用ParameterizedThreadStart,定義的引數必須為object型別。
class Program { static void Main(string[] args) { Thread t1 = new Thread(PrintNumbersWithDelay); t1.Start(); PrintNumbers(); Console.ReadLine(); } static void PrintNumbers() { Console.WriteLine("1.Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine("In 1.Starting: " + i); } } static void PrintNumbersWithDelay() { Console.WriteLine("2.Starting..."); for (int i = 0; i < 10; i++) { //var a = TimeSpan.FromSeconds(2); Thread.Sleep(TimeSpan.FromSeconds(2));//暫停兩秒 Console.WriteLine("In 2.Starting: " + i); } } }
註釋:使用Thread.Sleep(TimeSpan.FromSeconds(2));暫停執行緒一段時間
class Program { static void Main(string[] args) { Console.WriteLine("Starting..."); Thread t = new Thread(PrintNumbersWithDelay); t.Start(); t.Join(); //使用Join等待t完成後,再向下執行PrintNumbers,如果註釋掉輸出明顯不同 PrintNumbers(); Console.WriteLine("Thread Complete"); Console.ReadLine(); } static void PrintNumbers() { Console.WriteLine("1.Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine("In 1.Starting:" + i); } } static void PrintNumbersWithDelay() { Console.WriteLine("2.Starting..."); for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("In 2.Starting:" + i); } } }
註釋:使用t.Join(); 等待t完成。
class Program { static void Main(string[] args) { Console.WriteLine("Starting Program..."); Thread t1 = new Thread(PrintNumbersWithDelay); t1.Start(); Thread.Sleep(TimeSpan.FromSeconds(7));//此時t1執行緒會執行7秒 t1.Abort(); //使用Abort()終止執行緒 Console.WriteLine("Thread t1 has been aborted"); Thread t2 = new Thread(PrintNumbers); t2.Start(); Console.ReadLine(); } static void PrintNumbers() { Console.WriteLine("1.Starting..."); for (int i = 0; i < 10; i++) { Console.WriteLine("In 1.Starting:" + i); } } static void PrintNumbersWithDelay() { Console.WriteLine("2.Starting..."); for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("In 2.Starting:" + i); } } }
註釋:使用Thread範例的Abort方法終止執行緒。
class Program { static void Main(string[] args) { Console.WriteLine("Start Program..."); Thread t1 = new Thread(PrintNumbersWithStatus); Thread t2 = new Thread(DoNothing); Console.WriteLine("t1 status:" + t1.ThreadState.ToString());//獲取範例執行緒狀態 t2.Start(); t1.Start(); for (int i = 0; i < 30; i++) { Console.WriteLine("t1 status:" + t1.ThreadState.ToString() + "t" + "t2 status:" + t2.ThreadState.ToString()); } Thread.Sleep(TimeSpan.FromSeconds(7)); t1.Abort(); Console.WriteLine("thread t1 has been aborted"); Console.WriteLine("t1 status:" + t1.ThreadState.ToString()); Console.WriteLine("t2 status:" + t2.ThreadState.ToString()); Console.ReadLine(); } private static void PrintNumbersWithStatus() { Console.WriteLine("1.Starting..."); Console.WriteLine("In 1.Starting t1 status:" + Thread.CurrentThread.ThreadState.ToString());//獲取當前執行緒狀態 for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("In 1.Starting:" + i); } } private static void DoNothing() { Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("t2 Console..."); } }
註釋:使用Thread.ThreadState獲取執行緒的執行狀態。ThreadState是一個C#列舉。謹記:不要在程式中使用執行緒終止,否則可能會出現意想不到的結果
class Program { static void Main(string[] args) { //讓作業系統的所有執行緒執行在多個CPU核心上 Console.WriteLine($"Current thread priority: {Thread.CurrentThread.Priority}"); Console.WriteLine("Running on all cores available");//獲取範例執行緒狀態 RunThreads(); Thread.Sleep(TimeSpan.FromSeconds(2)); Console.WriteLine("Running on a single Core"); //讓作業系統的所有執行緒執行在單個CPU核心上 Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1); RunThreads(); Console.ReadLine(); } private static void RunThreads() { var sample = new ThreadSample(); var t1 = new Thread(sample.CountNumbers); t1.Name = "Thread One"; var t2 = new Thread(sample.CountNumbers); t2.Name = "Thread Two"; t1.Priority = ThreadPriority.Highest;//使用Priority設定執行緒的優先順序 t2.Priority = ThreadPriority.Lowest; t1.Start(); t2.Start();//此處t2優先順序低於t1,t2等待t1釋放資源。 Thread.Sleep(TimeSpan.FromSeconds(2)); sample.Stop(); } } class ThreadSample { private bool _isStopped = false; public void Stop() { _isStopped = true; } public void CountNumbers() { long counter = 0; while (!_isStopped) { counter++; } Console.WriteLine($"{Thread.CurrentThread.Name} with {Thread.CurrentThread.Priority} priority has a count={counter.ToString("N0")}"); } }
註釋:單核執行多執行緒耗費的時間比多核的多很多。
class Program { static void Main(string[] args) { var sampleForground = new ThreadSample(10); var sampleBackground = new ThreadSample(20); var t1 = new Thread(sampleForground.CountNumbers);//方法的參照 t1.Name = "ForegroundThread"; //沒有明確宣告的均為前臺執行緒 var t2 = new Thread(sampleBackground.CountNumbers); t2.Name = "BackgroundThread"; t2.IsBackground = true; //設定為後臺執行緒 t1.Start(); t2.Start(); Console.ReadLine(); } } class ThreadSample { private readonly int _iteration; public ThreadSample(int iteration) { _iteration = iteration; } public void CountNumbers() { for (int i = 0; i < _iteration; i++) { Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{Thread.CurrentThread.Name} prints {i}"); } } }
註釋:程序會等待所有的前臺執行緒完成後再結束工作,但是如果只剩下後臺執行緒,則會直接結束工作。
class Program { static void Main(string[] args) { ThreadSample sample = new ThreadSample(5); Thread t1 = new Thread(sample.CountNumbers); t1.Name = "ThreadOne"; t1.Start(); t1.Join(); Console.WriteLine("--------------------------"); Thread t2 = new Thread(Count); t2.Name = "ThreadTwo"; t2.Start(3); t2.Join(); Console.WriteLine("--------------------------"); //使用lambda表示式參照另一個C#對方的方式被稱為閉包。當在lambda表示式中使用任何區域性變數時,C#會生成一個類,並將該變數作為該類的一個屬性,但是我們無須定義該類,C#編譯器會自動幫我們實現 Thread t3 = new Thread(() => CountNumbers(5)); t3.Name = "ThreadThree"; t3.Start(); t3.Join(); Console.WriteLine("--------------------------"); int i = 10; Thread t4 = new Thread(() => PrintNumber(i)); i = 20; Thread t5 = new Thread(() => PrintNumber(i)); t4.Start(); t5.Start(); //t4, t5都會輸出20, 因為t4,t5沒有Start之前i已經變成20了 Console.ReadKey(); } static void Count(object iterations) { CountNumbers((int)iterations); } static void CountNumbers(int iterations) { for (int i = 1; i <= iterations; i++) { Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{Thread.CurrentThread.Name} prints {i}"); } } static void PrintNumber(int number) { Console.WriteLine(number); } } class ThreadSample { private readonly int _iteration; public ThreadSample(int iteration) { _iteration = iteration; } public void CountNumbers() { for (int i = 1; i <= _iteration; i++) { Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{Thread.CurrentThread.Name} prints {i}"); } } }
class Program { static void Main(string[] args) { Console.WriteLine("Incorrect Counter"); Counter c1 = new Counter(); var t1 = new Thread(() => TestCounter(c1)); var t2 = new Thread(() => TestCounter(c1)); var t3 = new Thread(() => TestCounter(c1)); t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); Console.WriteLine($"Total Count: {c1.Count}"); Console.WriteLine("------------------------"); //使用LOCK關鍵字,Count同一時刻只允許一個執行緒存取 Console.WriteLine("Correct counter"); CounterWithLock c2 = new CounterWithLock(); t1 = new Thread(() => TestCounter(c2)); t2 = new Thread(() => TestCounter(c2)); t3 = new Thread(() => TestCounter(c2)); t1.Start(); t2.Start(); t3.Start(); t1.Join(); t2.Join(); t3.Join(); Console.WriteLine($"Total count:{c2.Count}"); Console.ReadLine(); } static void TestCounter(CounterBase c) { for (int i = 0; i < 100000; i++) { c.Increment(); c.Decrement(); } } //子類 class Counter : CounterBase { public int Count { get; private set; } //重寫基礎類別方法 public override void Decrement() { Count--; } public override void Increment() { Count++; } } //子類 class CounterWithLock : CounterBase { private readonly object _asyncRoot = new object(); public int Count { get; private set; } //重寫基礎類別方法 public override void Decrement() { lock (_asyncRoot) { Count--; } } public override void Increment() { lock (_asyncRoot) { Count++; } } } //基礎類別 abstract class CounterBase { public abstract void Increment(); public abstract void Decrement(); } } class ThreadSample { private readonly int _iteration; public ThreadSample(int iteration)//建構函式 { _iteration = iteration; } public void CountNumbers() { for (int i = 1; i <= _iteration; i++) { Thread.Sleep(TimeSpan.FromSeconds(0.5)); Console.WriteLine($"{Thread.CurrentThread.Name} prints {i}"); } } }
註釋:不加鎖,得出的結果不確定,競爭條件下很容易出錯。加鎖得出的結果是正確的,但是效能受到了影響
class Program { static void Main(string[] args) { object lock1 = new object(); object lock2 = new object(); new Thread(() => LockTooMuch(lock1, lock2)).Start(); lock (lock2) { Thread.Sleep(1000); Console.WriteLine("Monitor.TryEnter allows not to get stuck, returning false after a specified timeout is elapsed"); //直接使用Monitor.TryEnter, 如果在第二個引數之前還未獲取到lock保護的資源會返回false if (Monitor.TryEnter(lock1, TimeSpan.FromSeconds(5))) { Console.WriteLine("Acquired a protected resource successfully"); } else { Console.WriteLine("Timeout acquiring a resource"); } } new Thread(() => LockTooMuch(lock1, lock2)).Start(); Console.WriteLine("-----------------------------"); /* 下面程式碼會造成死鎖, 所以註釋掉 lock (lock2) { Console.WriteLine("This will be a deadlock!"); Thread.Sleep(1000); lock (lock1) { Console.WriteLine("Acquired a protected resource successfully"); } } */ } static void LockTooMuch(object lock1, object lock2) { lock (lock1) { Thread.Sleep(1000); lock (lock2); } } }
註釋:Monitor.TryEnter在指定的時間內嘗試獲取指定物件上的排他鎖
class Program { static void Main(string[] args) { Thread t = new Thread(FaultyThread); t.Start(); t.Join(); try { t = new Thread(BadFaultyThread); t.Start(); } catch (Exception ex) { Console.WriteLine("We won't get here"); } } static void BadFaultyThread() { Console.WriteLine("Starting a bad faulty thread....."); Thread.Sleep(TimeSpan.FromSeconds(2)); //這個異常主執行緒無法捕捉到,因為是在子執行緒丟擲的異常。需要在子執行緒中加入try...catch捕獲異常 throw new Exception("Boom!"); } static void FaultyThread() { try { Console.WriteLine("Starting a faulty thread..."); Thread.Sleep(TimeSpan.FromSeconds(1)); throw new Exception("Boom!"); } catch (Exception ex) { Console.WriteLine($"Exception handled: {ex.Message}"); } } }
到此這篇關於c#多執行緒之執行緒基礎的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45