Linux多線程及多線程并發訪問同一塊內存的問題怎么解決

為什么需要多線程?

  • 并行實體共享同一個地址空間和所有可用數據 的這種能力是多進程鎖無法表達的,因為多進程具有不同的地址空間;

  • 線程比進程更加輕量級,更加快速;

  • 需要大量IO處理和計算時,擁有多線程,能夠很明顯地提升性能;

  • 在多CPU系統中,多線程是有益的,在這樣的系統中,能夠真正實現物理上的多線程并行運行;

多線程的優點

  • 加快程序響應速度;

  • 當前無需要處理的任務時,可將處理器時間讓給其他任務;

  • 占用大量處理時間的任務可以定期將處理器時間讓給其他任務;

  • 可以隨時停止任務;

  • 可以分別設置各個任務的優先級以優化性能;

最佳應用場景

  • 耗時或大量占用處理器的任務阻塞用戶界面操作;

  • 各個任務必須等待外部資源;(如遠程連接或INternet連接)

多線程的缺點

  • 等候使用共享資源時會使得程序的運行速度變慢,這些共享資源主要是獨占性資源,如打印機;

  • 對線程進行管理需要額外的CPU開銷;

  • 線程的死鎖,即較長時間等待或資源競爭,

  • 對公有變量的同時讀或寫往往會產生無法預知的錯誤

驗證思路

對同一個全局變量(初始值為0),使用五個線程函數進行++操作,每個線程函數++1000次,因此,我們5個線程就應該++5000次,最后該全局變量的值應該為5000。

Linux多線程及多線程并發訪問同一塊內存的問題怎么解決

執行不同次的嘗試,結果發現 wg 值有時為 5000,有時為 4997 或 4998。?

原因是:

我們對wg++,并不是原子操作,轉換為指令,有多條指令構成,計算機執行的二進制的指令對變量的自增這一操作分了很多步驟,比如有兩條線程對wg++

但是++不是一下子可以完成,先將val讀過來,再++,再讀回去,這個操作還沒結束,另外一個線程也把wg讀過來,++,再讀回去。有可能兩個線程對wg=1;進行加加,最后值卻為2。

我們不能僅僅停留在代碼層面考慮問題,我們還需要考慮代碼運行的環境,觀察我們虛擬機的設置發現:有4個處理器,至少有兩個處理器有處理其他線程,存在一個線程放在2個處理器上的情況,同時訪問,出現小于5000的概率比較高,這也是因為并行執行引起的。

Linux多線程及多線程并發訪問同一塊內存的問題怎么解決

只啟用一個處理器后,只有一個線程在執行,其他四個線程肯定沒有執行,不存在同時執行兩個線程的情況。

出現小于5000的概率很小(這個原因是,把val值1讀過來,還沒來得及++回去,這個時候時間片到了,發生了切換,換到其余線程,讀過來還是1,加加,現場恢復,還是1進行加加,這種場景出現的概率非常小)1個處理器不能并行的。

? 版權聲明
THE END
喜歡就支持一下吧
點贊11 分享