從找對象到多執行緒

  • 2019 年 10 月 4 日
  • 筆記

最近遇到了一個和多執行緒有關的事,順便簡單複習了下相關概念,稍後舉個栗子?來解釋下。

進程 and 執行緒

進程我們都知道,就是應用程式的啟動實例。比如我們運行一個遊戲,打開一個軟體,就是開啟了一個進程。

而執行緒從屬於進程,是程式的實際執行者。一個進程至少包含一個主執行緒,也可以有更多的子執行緒。

我們可以簡單的理解:為了做一件事,我開了一個進程,為了讓這件事更有效率的完成,我開了多個執行緒。

從找對象入手加深理解

如果這麼說還是不清楚的話,我們以一個找對象的例子來加深理解:

讀研了,望著身邊的小夥伴一個個都是成雙成對,筆者有一個萬年單身的好基友就跟一條酸菜魚似的(又酸又菜又多餘),想著要不也找個女朋友吧?於是就創建了一個名為「找對象」的進程。但是學校女生太多了,如果一個一個試的話不知道啥時候才能脫單。這時候,萬能的度娘給出了建議,為什麼不同時下手呢?

於是,他就創建了兩個「撩妹」的執行緒,每個執行緒負責撩一個妹子。但這時就有問題出來了。

雖然他可以同時撩兩個妹子,但是有些事情就是沒辦法同時和兩個妹子做,比如上課、吃飯、散步。這個時候就需要「數據保護」。做這些事情的時候,他一次只能跟一個妹子做,這就叫做「臨界區」。他撩的兩個妹子,一個是紅玫瑰,一個是白玫瑰,各有各的特點,這是她們的「私有屬性」。這兩個妹子都可以跟他約會,此時他就是一個「共享記憶體」。如果某一天他跟其中一個妹子在外面約會,那另一個撩妹執行緒就只能「阻塞」了。但是為了防止後院起火,不讓另一個妹子不爽,他就只能發條朋友圈說自己在學習,不想被打擾,這就叫「互斥鎖」。同時為了不讓她們影響對方的存在,他用QQ叫著其中一個的小名,微信卻是另一個的情侶頭像,這就是「消息傳遞」

上述兩個執行緒在某種意義上就構成了「競態條件」(個人認為叫做「競爭狀態」會更好)。如果他只有這兩個執行緒的話,想要完成「找對象」這個進程,就只能看這兩個執行緒誰的執行效率更高(其實就是看誰先運行完)了。這麼一看,我的好基友貌似很快就可以完成「找對象」這一進程了,因為無論是哪個執行緒,只要有一個「撩妹」執行緒結束了,整個進程也就結束了。

但是在結束前可能會出現一些問題(注意這裡是可能),如果他在排約會檔期時一旦沒有進行良好的調度,就很有可能會出現兩個妹子約在同一天約會,基友卻沒辦法到達的情況,這種情況就叫「死鎖」,即較長時間的等待或資源競爭。亦或是如果不幸被兩個妹子都發覺了對方的存在,卻又為表大度,你讓我我讓你,最終導致「找對象」進程無法進行下去,這就叫做「活鎖」。如果此時出現了一個「工具人」妹子,主動倒追我基友,這樣的話即使被加入了「找對象」的進程,也可能會因為一系列問題始終沒法和他單獨約會(畢竟還有兩個「撩妹」執行緒在進行著),這種情況就叫做「飢餓」。這三種情況總結一下就是:

  1. 死鎖:爭來爭去 誰也得不到
  2. 活鎖:讓來讓去 誰都不擁有
  3. 飢餓:排多久 都輪不到自己

倘若我基友最後撩成功的女朋友並不是他最喜歡的那個人,即最終的運行結果和預期不同,這就叫「執行緒不安全」。反之,如果最後撩成功的妹子是他最喜歡的,即最終的結果和預期相同,那這個就叫「執行緒安全」

這麼一看,真是人生如戲。只是可悲的是,我本以為現在執行的是一個單進程,卻沒想到也只是別人的一個執行緒罷了。