c# 多线程 执行事件 并发_C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础...
因為平時挺少用到多線程的,寫游戲時都在用協程,至于協程那是另一個話題了,除了第一次學習多線程時和以前某個小項目有過就挺少有接觸了,最近準備面試又怕被問的深入,所以就趕緊補補多線程基礎。
網上已經有很多線程編程的學習筆記了,那我為什么還要再整理一篇呢。因為我在搜索網上文章的時候發現一般別人整理的面試文章那很多語法都一筆帶過了默認大家都懂,學習文章又很少有給出經典的題目,一般都是要幾篇集合著一起看,既然如此的話我為什么不自己整理出一份呢?自己看的輕松,說不定以后也有人喜歡這種風格能幫助到別人。所以這篇文章也會參考很多其他的文章,最后都會寫上引用的。
我寫算法的時候也是很喜歡用C++ 來學習,而且筆試的時候我或者很多公司也喜歡用C++,畢竟C++ 的控制臺程序輸入輸出格式化做的也比較好,那為什么這篇又用的是C#而不是C++ 呢?因為最近實習只帶著筆記本,我的筆記本上只裝了vscode用來寫輕量級程序學習。C++裝的是MinGW來編譯,但是MinGW因為跨平臺吧對std::thread支持的又不太好,反正又不是不會用別的語言,最重要的是學習的思想嘛。
一、進程和線程有什么區別?為什么要使用多線程?
首先用最經典的一道面試題作為引入。
①進程是資源分配的最小單位,線程是CPU調度的最小單位。
②一個線程只能屬于一個進程,而一個進程可以有多個線程。
③進程在執行過程中擁有獨立的內存單元,而多個線程共享進程的內存。
④進程間不會相互影響 ;線程一個線程掛掉將導致整個進程掛掉。
⑤進程編程調試簡單可靠性高,但是創建銷毀開銷大;線程正相反,開銷小,切換速度快,但是編程調試相對復雜。
⑥部分任務可能比較耗時,長時間占用CPU(你肯定不希望應用執行某個功能時整個程序都卡死),如果創建進程解決可能額外CPU開銷更大,因此部分時候需要使用多線程技術。
二、C# 中使用多線程
在 C# 中,System.Threading.Thread 類用于線程的工作。它允許創建并訪問多線程應用程序中的單個線程。進程中第一個被執行的線程稱為主線程。 當 C# 程序開始執行時,主線程自動創建使用 Thread 類創建的線程被主線程的子線程調用。
再介紹Thread類中比較有用的一個靜態方法,Sleep,用于掛起(可以看成暫停)線程一段時間,參數是毫秒。
下面來一個簡單的例子看Thread的使用:
執行該程序首先暫停1秒(1000毫秒),接著連續輸出 我是不帶參數的線程我是帶參數的線程
然后再暫停1秒,接著輸出我是不帶參數的線程
一開始是在主線程中掛起(暫停)的,所以兩個線程都要等1秒才執行,后面是在不帶參數的線程中掛起的,不影響另一個線程,所以帶參數的線程就直接輸出了。
但是要注意的是我這里是在Thread直接指定了方法,但實際上該方法有委托類型
所以說剛剛的實例化可以展開成如下形式
Thread這里的參數用的是object,有可能會被問到一個問題就是拆箱裝箱,當然拆箱裝箱和之前提的委托,包括什么匿名函數、lambda之類的都是另一個話題了,這里為了保持知識的獨立性不過多的引入其他特性了,只在必要的時候講。
三、資源搶占與信號
上面的內容十分簡單,似乎跟普通的實例化類調用下函數沒什么區別啊。
那我們再用一道面試題作為引入:
兩個線程交替打印0~100的奇偶
如果只用上面的知識寫出下面的代碼,那運行一下就可以發現問題所在了。
using結果:
當然這個結果不一定是一樣的,畢竟是兩個線程并發在跑,但是卻只有一個控制臺啊,當然,往深一點說就是多個線程共享的資源。
就像十字路口如果不控制車輛開動的順序,仍由他們亂開會引發嚴重的后果一樣,實際上我們在編程中也經常會遇到控制線程順序的需求。
那說到這其實也很好理解了,就跟十字路口需要紅綠燈一樣,我們也會用到信號燈的思想去控制線程的執行順序。
在C#中有封裝好類EventWaitHandle(并不嚴謹,下期說,這期是為了方便理解概念),有幾個成員方法,
WaitOne():如果是紅燈的話會將線程暫停在當前位置。
Set():相當于開綠燈,允許被暫停的線程通過開始執行下面的代碼了
Reset():相當于開紅燈,線程遇到wait會暫停住。
EventWaitHandle必須指定一個枚舉類型,AutoReset或ManualReset,ManualReset很好理解,就是手動開關紅綠燈。而AutoReset是指在執行Set()后會馬上自定執行一次Reset(),相當于只是把當前在紅燈前的線程放行。
那么有了這些知識我們就可以開始寫代碼了
當然,這里寫成開了兩個flag完全是為了方便理解,事實上可以只開一個叫flag,然后把evenFlag和oddFlag都改成flag,畢竟只有兩個線程,要么停要么走嘛。
最后我們似乎能把兩個函數再合成成為一個函數,但是這樣的話單單一個信號燈似乎是沒辦法解決的了,可以像上面用兩個信號量或者下篇還有機會出來的話講講鎖。
引用:
.NET面試題解析(07)-多線程編程與線程同步-/夢里花落知多少/
Thread Class-MSDN
C#多線程-菜鳥教程
EventWaitHandle Class-MSDN
多線程C#面試題-Ax0ne
總結
以上是生活随笔為你收集整理的c# 多线程 执行事件 并发_C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 商业 AI 图像生成服务 Midjour
- 下一篇: OPPO Find X6 Pro将支持W