【中低階級】-執行緒Thread-使用-2

閱讀時間約 8 分鐘
接續上一篇分享跟執行緒相關的內容包含:安全鎖(lock)、號誌(semaphore)、前景與背景執行緒介紹等等。直接來啦~

二、安全鎖(lock)

  安全鎖目的是當多個執行緒要執行同一函式時,為了避免同時進行或是影響到變數的值,因此才會有這個機制來保護。「鎖的是區塊」而非資源哦!什麼意思?來看看就知道了, 先介紹相關的一些名詞吧!

1. 互斥鎖(mutex)

  由於會有多個執行緒在執行,對於全域變數的部分(也就是共享資源)就有可能會在不同的區塊同時使用到同一變數(同一資源),此時程式就很容易錯亂,就像是我們在心算時若要同時進行A+B和A-B時是不是就很容易運算錯誤呢?因為腦袋出現兩條要執行的內容並且還使用同變數,所以很容易出錯呀!電腦也是一樣的道理,因此設計了一個機制就是可以配合Lock和mutex一起使用比較不會錯亂。
結論:互斥鎖(mutex)的目的就是在同一時間限制只有一個執行緒可以使用同一變數(同一資源)不讓電腦執行錯誤,直到此執行緒釋放了這個變數(資源)才可以讓下一個執行緒來使用。(也就是排隊輪流概念)
使用互斥鎖(mutex)時會用到兩個方法它們一定是搭配使用的,也就是:
Mutex.WaitOne();        //獲取(拿取)鎖
Mutex.ReleaseMutex();   //釋放(歸還)鎖
實際看一下例子:
mutex-程式碼
mutex-執行結果
說明:
【程式】
第1區(也就是第173行)先建立全域變數的Mutex
第2區(第175-188行)這邊是主程式,也就是按鈕的程式
第3區(第190-200行)這邊就是在使用互斥鎖(Mutex)的方法,先拿到鎖才可以進行想要做的事,做完後就要歸還鎖。

【結果】
此時電腦跑的執行緒並不一定會乖乖從1-4慢慢執行,但是它會乖乖的將拿到鎖的執行緒把要做的事全部做完才會釋放掉,大家可以用逐步執行或設中斷點來一步步看程式是如何運作的。
以上是互斥鎖(mutex)的用法。

2. 監測執行緒(monitor)

  它是安全鎖(Lock)的底層,所以很多人都說lock是monitor的「語法糖」,因為lock會對monitor的Enter和Exit進行封裝,monitor可以做的事比lock多,因為lock就只是個開關。
科普一下:
什麼是「語法糖」?
就是可以讓程式更加簡潔、提高可讀性哦!!
讓程式寫起來有甜甜的滋味,有沒有很貼心呀~哈哈

它也又稱為「糖衣語法」。
說成這樣到底monitor是有多複雜?還需要有這顆神秘魔法的語法糖來增加寫程式的甜度嗎?
還是擔心程式設計師寫到太常理性思考,感性部分都被抹除了呢?這或許是另類的貼心哦!哈哈
我們就依序慢慢看吧~就當看故事好哩!
先將互斥鎖(mutex)對應過來看監測執行緒(monitor)的狀況:
monitor-程式碼
monitor-執行結果
轉過來其實都差不多,幾乎可以說一樣的,只差在於它有參數而已,那哪來需要語法糖呀!真是個好問題(我也沒有深度使用過,所以目前也還不知道)
有些程式會加try...catch...finally...,這是擔心倘若中途發生異常時至少鎖要被釋放掉還給系統,為了避免此情形產生才會加進去。
那麼不是說monitor還有其他方法?是的!這邊先列出兩個方法感覺比較常用到的:
Monitor.TryEnter(object , ms );
//設置對象(object)只提供毫秒數(ms)的時間,時間道則會釋放該鎖
//這是為了避免「死鎖」的現象
Monitor.IsEntered(object);
//用來判斷目前執行緒是否保持鎖定的指定物件
OK那麼就回來看一下安全鎖Lock是怎麼使用的吧~

3. 安全鎖(lock)

lock-程式碼
lock-執行結果
說明:
【程式】
第一區塊的主程式都跟上面差不多。
第二區塊是改變最大的了,那麼上面的mutex和monitor都是需要用一對的程式去控制鎖的獲取與釋放,那Lock這邊只需要將要鎖起來部分lock起來即可。兩者的程式差異就在這裡。

【結果】
這邊一開始我用一些符號或文字來代表程式進入的狀況。
可以從結果得知UseLock_Count是先一個執行緒做完後才會有下一個執行緒進來。
~~~~~~~~~~~~~~~~~[筆記]~~~~~~~~~~~~~~~~~
上面例子尚未用到Class類別都是先以基本的先了解後往後再進階,那當使用lock時需要注意以下事項:
1.當實例是public時最好不要lock(this),因爲使用你的class的人也許不知道你用了lock,如果他new了一個實例,並且對這個實例上鎖,就很容易造成「死鎖」。
2.如果MyType是public的,不要lock(typeof(MyType))。
3.永遠也不要lock一個字符串。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

三、號誌(semaphore)

  號誌可以限制多個執行緒數量同時進入函式區塊裡,它的用法要先建立建構函式:
private Semaphore semaphore1 = new Semaphore(2,5);
//第一個參數為:允許同時進入的執行緒數量
//第二個參數為:允許可容納多少執行緒數量在此區域中
//所以要注意 第一個參數 不可大於 第二參數
semaphore1 .WaitOne();
//堵住執行緒進來
//也就是說當執行緒已達到設定的數量就把門關上不讓執行緒進來,直到後面的Release()釋放執行緒後就會丟出訊號通知WaitHandle,也就是這邊WaitOne會收到訊號就會開門繼續讓執行緒進來,這一行也可以說是「守門員」
semaphore1.Release(1);
//參數是指要釋放多少個執行緒,也就是訊號出來
//功能:釋放執行緒訊號丟出訊號通知給WaitHandle
就直接先來看一下它實際怎麼運作的:
semaphore-程式碼
semaphore-執行結果按鈕
semaphore-執行結果
說明:
【程式】
1.第一區塊(也就是第276行)先建立建構函式
2.第二區塊就是主程式,一樣先建立執行緒,為了方便了解也設定該執行緒名字
3.第三區塊就是使用號誌的地方了,比較有問題的應該是 ((int)obj+1) ,(int)obj這個是指將obj強制轉換為int型態,轉換完後再將數值+1,那麼它與Thread.CurrentThread.Name有何不一樣?這一個是指我們主程式那邊所設定的Name名字,那 (int)obj就是電腦對此執行緒給予的一個編號。

【結果】
  這邊用文字顯示讓大家看比較好懂一點程式怎麼執行的,那麼對於剩餘的執行數量這邊大家可以等程式跑完後自行畫圖,看看區塊中進入或移出的狀況,不了解也還可以自己修改號誌執行緒進入的數量再去try try看,或者也可以去修改主程式中要給予多少個執行緒,修改幾次多看幾次就會更好懂了。
這個必須動手操作才會比較好了解,否則用看的的確感覺很難,事實上動手操作一遍,再看一下每一行功能與作用就會好懂很多。

四、前景與背景執行緒

  當我們使用者不管它時,它也還會在背後默默進行著直到結束,這個就稱為「背景執行緒」。用音樂來說大家一定有這個經驗想要邊上網做作業時把音樂開起後就不管它了,這個就是背景執行緒,那前景執行緒呢?
當主程式new 出一個新的執行緒此時預設皆為前景執行緒,也就是
Thread.IsBackground=false; 
那麼對於執行緒來說當主程式下達了中止命令時,當前景執行緒有任一個還未完成的,它會等他完成後才會執行中止的動作。但被景執行緒就不一樣了,一旦收到中止命令時,就會直接立即中止。

為什麼會看到廣告
avatar-img
21會員
43內容數
Hello~ Welcome to my blog~❤ 這邊會分享我在程式這條道路中的學習與成長, 過程中從而了解自己的不足,再學習。 希望透過分享的方式, 也讓正在學習程式的夥伴們一起學習, 我們一起加油吧~ 「彼此都會成為彼此之間的影響力」(´,,•ω•,,)♡ ❣
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
橙果杏的沙龍 的其他內容
  當我們要使用執行緒的時候,就要引用System.Threading的類別庫,程式才可以使用唷!這篇內容先說明:建立與啟用執行緒、跨執行緒控制UI介面、等待或暫停時間執行緒、共享資源的部分。
  在說執行緒(Thread)時就要先知道什麼是程式(Program)、程序(Process),才能了解什麼是執行緒(Thread),因為它們間都有著神秘的關係與關聯,再更深入一點就又會有多程序(muti-Process)、多執行緒(muti-Thread),我們就先一一說明好了,了解它們後再使用時
  程式在執行的過程中難免會遇到意外的狀況發生,這時該怎麼辦呢?現實生活中我們可能就會去保保險,那麼程式怎麼辦?有一個例外處理try...catch可以幫我們解決這個問題,甚至還可以使用throw可以丟出例外,例外處理部分是可以透過程式的規劃來了解是哪邊出問題的哦!怎麼說呢?我們來看一下例子:
  本篇要分享的是事件(Event)與委派(Delegate),這兩者時常都會綁再一起,怎麼說呢?我們先來各別了解什麼是Event?什麼是Delegate?他們都在做些什麼事呢? 一、事件(Event)   事件(Event)是事情的發生、狀態的發生或改變,也可以說是對於這件事去「做通知」這個動作。
  本篇要分享的內容包含Enum、Dictionary、Stack、Queue、IComparable<T>、IComparer<T>、CompareTo、Compare等等相關內容。它們與Array和List有些類似,都是資料集合存取或資料其他相關處理的部分,我們就來看一看它們是何方神聖吧~
  物件導向說到這邊其實修飾詞不只有之前所提的public、private這些,還有可能遇到抽象(abstract)、虛擬(virtual)、覆寫(override)、隱藏(new)、密封(sealed)、介面(interface)等等,我們就來看一下它們的差異吧~
  當我們要使用執行緒的時候,就要引用System.Threading的類別庫,程式才可以使用唷!這篇內容先說明:建立與啟用執行緒、跨執行緒控制UI介面、等待或暫停時間執行緒、共享資源的部分。
  在說執行緒(Thread)時就要先知道什麼是程式(Program)、程序(Process),才能了解什麼是執行緒(Thread),因為它們間都有著神秘的關係與關聯,再更深入一點就又會有多程序(muti-Process)、多執行緒(muti-Thread),我們就先一一說明好了,了解它們後再使用時
  程式在執行的過程中難免會遇到意外的狀況發生,這時該怎麼辦呢?現實生活中我們可能就會去保保險,那麼程式怎麼辦?有一個例外處理try...catch可以幫我們解決這個問題,甚至還可以使用throw可以丟出例外,例外處理部分是可以透過程式的規劃來了解是哪邊出問題的哦!怎麼說呢?我們來看一下例子:
  本篇要分享的是事件(Event)與委派(Delegate),這兩者時常都會綁再一起,怎麼說呢?我們先來各別了解什麼是Event?什麼是Delegate?他們都在做些什麼事呢? 一、事件(Event)   事件(Event)是事情的發生、狀態的發生或改變,也可以說是對於這件事去「做通知」這個動作。
  本篇要分享的內容包含Enum、Dictionary、Stack、Queue、IComparable<T>、IComparer<T>、CompareTo、Compare等等相關內容。它們與Array和List有些類似,都是資料集合存取或資料其他相關處理的部分,我們就來看一看它們是何方神聖吧~
  物件導向說到這邊其實修飾詞不只有之前所提的public、private這些,還有可能遇到抽象(abstract)、虛擬(virtual)、覆寫(override)、隱藏(new)、密封(sealed)、介面(interface)等等,我們就來看一下它們的差異吧~
你可能也想看
Google News 追蹤
Thumbnail
避免 thread 競速(Race Condition)是多執行緒編程中常見的挑戰之一。 Race Condition 發生在多個執行緒同時訪問和修改共享資源時,因為執行緒之間的執行順序無法預測,可能會導致數據的不一致性或意外行為。 本文主要介紹如何使用Lock來避免此狀況出現。 首先先看沒
Thumbnail
不少投资者都知道在区块链项目中存在很多骗局形式,其中出现最多的骗局就是项目方进行欺诈的行为,这能很大保护保护参与者的利益,了解完区块链时间锁用处,下面跟着小编一起来了解下区块链时间锁是什么意思? 🚀 币安 - 全球最大加密货币交易所 💥 独家优惠 💥 💰 注册即享 20% 手续费返佣
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
作者的話: 發現有些朋友對抽牌時的用詞很疑惑,所以特地畫了一篇專門解釋用~ 控制也有「把自己繃得太緊」的含意, 有點像是為了實現計劃、承諾,感受不到一開始的制定計劃時的動力的感覺。 通常這些人意志都很堅定,所以會更追求實踐目標, 所以比起"不要控制!!",更像是在說"太多了~你放掉一點,事情
※ 非同步概念總複習 為什麼要使用 Promise? 在 JavaScript 開發中,處理非同步操作是常見需求,涉及如文件讀寫、數據庫查詢或網路請求等耗時任務。傳統的回調方式可能導致代碼結構混亂,稱為「回調地獄」,難以維護和理解。 Promise 是解決這問題的方法。它是一個物件(objec
※ 同步概念: 單純地「由上而下」執行程式碼,而且一次只執行一件事,也就是「按順序執行,一個動作結束才能切換到下一個」。缺點是你需要「等待」事情執行完畢,才能繼續往下走。 ※ 非同步概念: 盡可能讓主要的執行程序不需要停下來等待,若遇到要等待的事情,就發起一個「非同步處理」,讓主程序繼續執行,
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
物件導向設計的一個重點就是封裝,這有很多層面上的意義,但基本上就是控制物件的成員變數和方法的存取權。物件導向的封裝還跟繼承機制有關,這使得有一些時候我們逼不得已必須把函式定義在類別上,這種做法使得物件的功能變得難以拆解。封裝應該是模組的職責,並不需要再給物件相同的能力。 一般的模組系統就是把相
Thumbnail
避免 thread 競速(Race Condition)是多執行緒編程中常見的挑戰之一。 Race Condition 發生在多個執行緒同時訪問和修改共享資源時,因為執行緒之間的執行順序無法預測,可能會導致數據的不一致性或意外行為。 本文主要介紹如何使用Lock來避免此狀況出現。 首先先看沒
Thumbnail
不少投资者都知道在区块链项目中存在很多骗局形式,其中出现最多的骗局就是项目方进行欺诈的行为,这能很大保护保护参与者的利益,了解完区块链时间锁用处,下面跟着小编一起来了解下区块链时间锁是什么意思? 🚀 币安 - 全球最大加密货币交易所 💥 独家优惠 💥 💰 注册即享 20% 手续费返佣
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
作者的話: 發現有些朋友對抽牌時的用詞很疑惑,所以特地畫了一篇專門解釋用~ 控制也有「把自己繃得太緊」的含意, 有點像是為了實現計劃、承諾,感受不到一開始的制定計劃時的動力的感覺。 通常這些人意志都很堅定,所以會更追求實踐目標, 所以比起"不要控制!!",更像是在說"太多了~你放掉一點,事情
※ 非同步概念總複習 為什麼要使用 Promise? 在 JavaScript 開發中,處理非同步操作是常見需求,涉及如文件讀寫、數據庫查詢或網路請求等耗時任務。傳統的回調方式可能導致代碼結構混亂,稱為「回調地獄」,難以維護和理解。 Promise 是解決這問題的方法。它是一個物件(objec
※ 同步概念: 單純地「由上而下」執行程式碼,而且一次只執行一件事,也就是「按順序執行,一個動作結束才能切換到下一個」。缺點是你需要「等待」事情執行完畢,才能繼續往下走。 ※ 非同步概念: 盡可能讓主要的執行程序不需要停下來等待,若遇到要等待的事情,就發起一個「非同步處理」,讓主程序繼續執行,
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
物件導向設計的一個重點就是封裝,這有很多層面上的意義,但基本上就是控制物件的成員變數和方法的存取權。物件導向的封裝還跟繼承機制有關,這使得有一些時候我們逼不得已必須把函式定義在類別上,這種做法使得物件的功能變得難以拆解。封裝應該是模組的職責,並不需要再給物件相同的能力。 一般的模組系統就是把相