84669 人學習
152542 人學習
20005 人學習
5487 人學習
7821 人學習
359900 人學習
3350 人學習
180660 人學習
48569 人學習
18603 人學習
40936 人學習
1549 人學習
1183 人學習
32909 人學習
不要通过共享内存来通信,而应该通过通信来共享内存
这是一句风靡golang社区的经典语,对于刚接触并发编程的人,该如何理解这句话?
光阴似箭催人老,日月如移越少年。
https://blog.golang.org/share...
這篇文章裡面說的比較清楚了,使用共享記憶體的話在多執行緒的場景下為了處理競態,需要加鎖,使用起來比較麻煩。另外使用過多的鎖,容易使得程式的程式碼邏輯堅澀難懂,並且容易使程式死鎖,死鎖了以後排查問題相當困難,特別是很多鎖同時存在的時候。
go語言的channel保證同一個時間只有一個goroutine能夠存取裡面的數據,為開發者提供了一種優雅簡單的工具,所以go原生的做法就是使用channle來通信,而不是使用共享記憶體來通信。
我認為前者的意思是大家都維護一個狀態,後者是每個人都維護一份狀態副本。
共享記憶體會涉及到多個執行緒同時存取修改資料的情況,那得確保資料的安全性,可見性,那就會加鎖,加鎖會讓並行變為串行,cpu也忙於執行緒搶鎖。不如換一種方式,把資料複製一份,每個執行緒有自己的,只要一個執行緒乾完一件事其他執行緒不用去搶鎖了,這就是一種通訊方式,把共享的以通知方式交給線程,實作並發
其實如果從分散式的角度來理解,就會比較明了。
打比方,ab兩個進程共同對同一個訊息佇列進行操作,那麼,如果使用共享記憶體的話,是不是這兩個進程就必須局限在同一個實體機上,那麼通訊的意義就大大縮小了。
如果在設計的時候,對於訊息隊列,只提供讀寫接口,而對於內部的實現你完全不用去在意,看起來消息隊列就像是共享內存一樣了。然而你的訊息隊列可以利用socket進行通訊。
所以,上述這句話,不要用共享內存實現通信是指不要讓程式一開始就局限在單機上,而是利用通信,也就是封裝內部實現,提供接口的方式來進行相應的操作
https://blog.golang.org/share...
這篇文章裡面說的比較清楚了,使用共享記憶體的話在多執行緒的場景下為了處理競態,需要加鎖,使用起來比較麻煩。另外使用過多的鎖,容易使得程式的程式碼邏輯堅澀難懂,並且容易使程式死鎖,死鎖了以後排查問題相當困難,特別是很多鎖同時存在的時候。
go語言的channel保證同一個時間只有一個goroutine能夠存取裡面的數據,為開發者提供了一種優雅簡單的工具,所以go原生的做法就是使用channle來通信,而不是使用共享記憶體來通信。
我認為前者的意思是大家都維護一個狀態,後者是每個人都維護一份狀態副本。
共享記憶體會涉及到多個執行緒同時存取修改資料的情況,那得確保資料的安全性,可見性,那就會加鎖,加鎖會讓並行變為串行,cpu也忙於執行緒搶鎖。不如換一種方式,把資料複製一份,每個執行緒有自己的,只要一個執行緒乾完一件事其他執行緒不用去搶鎖了,這就是一種通訊方式,把共享的以通知方式交給線程,實作並發
其實如果從分散式的角度來理解,就會比較明了。
打比方,ab兩個進程共同對同一個訊息佇列進行操作,那麼,如果使用共享記憶體的話,是不是這兩個進程就必須局限在同一個實體機上,那麼通訊的意義就大大縮小了。
如果在設計的時候,對於訊息隊列,只提供讀寫接口,而對於內部的實現你完全不用去在意,看起來消息隊列就像是共享內存一樣了。然而你的訊息隊列可以利用socket進行通訊。
所以,上述這句話,不要用共享內存實現通信是指不要讓程式一開始就局限在單機上,而是利用通信,也就是封裝內部實現,提供接口的方式來進行相應的操作