go數據類型-sync.map

来源:https://www.cnblogs.com/studyios/archive/2023/11/29/17864986.html
-Advertisement-
Play Games

Zlib是一個開源的數據壓縮庫,提供了一種通用的數據壓縮和解壓縮演算法。它最初由Jean-Loup Gailly和Mark Adler開發,旨在成為一個高效、輕量級的壓縮庫,其被廣泛應用於許多領域,包括網路通信、文件壓縮、資料庫系統等。其壓縮演算法是基於DEFLATE演算法,這是一種無損數據壓縮演算法,通常... ...


定義

在runtime的sync.map包中有定義:

type Map struct {
	mu Mutex // 鎖
	read atomic.Pointer[readOnly] //包含了readOnly類型的一個struct,下方把 Pointer 也貼了
	dirty map[any]*entry	 // 一個map 存儲數據
	misses int          // 錯過、沒有命中
}

// readOnly is an immutable struct stored atomically in the Map.read field.
type readOnly struct {
	m       map[any]*entry // 一個map,這個map是 read持有的
	amended bool // true if the dirty map contains some key not in m.
    // 追加,這裡已經註釋了 當dirty 的map中的key 不在 m的map中(就是 read的)就顯示為 true
}

// go 的泛型
type Pointer[T any] struct {
	_ [0]*T
	_ noCopy
	v unsafe.Pointer
}

整體的結構就如上圖。

sync.map中有兩個map 都是通過指針的形式 ,指向同一份value,但是key兩個map都有各自存儲。

分析原理

看究竟是如何解決map併發的問題的。

正常讀寫

正常讀寫走 m,就是read那個通過泛型結構體指向的那個 map,通過m這個map進行查找後,讀取或者更改。

這個時候 misses = 0 ,amended=false

追加

如何寫一個key,發現m中沒有,那麼需要去dirty中追加。

開始追加前,需要對dirty進行上鎖,寫完解鎖

如圖現在追加了一個 d,這個時候 m中沒有這個d的信息。

這個時候 misses = 0 ,amended=true 這個時候有了 dirty的key 不在m中了。

追加後讀寫

這時候就會出現 找d時候,發現m中沒有並 amended=true ,就會去 dirty中找,而且每找一次,都會給 misses 加1

這個時候 misses = 1 ,amended=true 

dirty 提升

misses 等於 len(dirty) 就會觸發dirty提升,替代m。

當再次出現追加的情況,重塑 dirty

這時候把  misses = 0 ,amended=false 複原

刪除

刪除比較麻煩,分為正常刪除,和在上面的各種狀態下進行刪除。

正常刪除

只需要把pointer置為nil就好,value因為沒有對象指向它,在垃圾回收時候,會被標記為白色,被清理。

追加後刪除

正常也是置為nil

刪除後,提升

提升之後,如果重建 dirty,就不會重建這個d

這裡d標記為 expunge 是為了告訴下方,
這個key已經被刪除了,不用同步了,如果出現刪除d的請求,不需要和下方dirty同步了。
而且當再對D進行追加時候,這時候 m中有d,但是,應該要放到dirty中去完成。

總結:

1. map 在擴容時會有併發問題

2.sync.Map 使用了兩個map,分離了擴容問題

3.不會引發擴容的操作(查、改)使用read map

4.可能引發擴容的操作(新增)使用 dirty map

5.不是採用讀寫分離的辦法


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當使用Spring Boot整合HikariCP時,您可以更加詳細地配置和優化連接池以獲得更好的性能。以下是更詳細的步驟和示例代碼: 步驟1:創建Spring Boot項目 您可以使用Spring Initializr(https://start.spring.io/)創建一個新的Spring Bo ...
  • Quora 的流量涉及大量閱讀而非寫入,一直致力於優化讀和數據量而非寫。 0 資料庫負載的主要部分 讀取 數據量 寫入 1 優化讀取 1.1 不同類型的讀需要不同優化 ① 複雜查詢,如連接、聚合等 在查詢計數已成為問題的情況下,它們在另一個表中構建了計數,以便它們可以直接讀取計數值而非計算計數。 ② ...
  • 寫在前面 最近比較迷AI繪圖,那就上個圖吧,我感覺還挺好看的。 可能會有人說,之前不一致分享的是flask嗎,怎麼突然改到django了? 這個問題問得好,開發環境遇到了一些小困難! 不過django,真的是很流行,一點都不過時,這您放心好了!不多說,直接看效果吧! 環境搭建 1、當前環境版本 py ...
  • and dest,src將目標與源做與操作 or dest,src將目標與源做或操作 add 加得數的值超出範圍即會溢出 inc 彙編語言中的自增指令,相當於++ div指令 不會給出被除數 切記提前在預設的寄存器中設置好被除數,且預設寄存器不做別的用處 dup設置記憶體空間,與db、dw、dd等數據 ...
  • 概述 - Overview 在我初學 C++ 時,static、inline、extern 可能是最令我迷惑的 C++ 說明符,原因是它們在不同的語境下會發揮不同的作用,而且某些說明符的含義已經和以前不同,這加劇了我在查詢資料時的困擾。所以今天決定好好總結一下。 首先要介紹 C++ 的兩個概念:存儲 ...
  • 哈嘍大家好,我是鹹魚 當我們在學習 Python 的時候,可能會經常遇到單下劃線 _ 和雙下劃線 __ 這兩種命名方式 單下劃線 _ 和雙下劃線 __ 不僅僅是只是一種簡單的命名習慣,它們在 Python 中有著特殊的含義,對於代碼的可讀性和功能實現有著關鍵的作用。 那麼今天我們來看一看在 Pyth ...
  • LinkedList是Java中的一個雙向鏈表。它實現了List和Deque介面,在使用時可以像List一樣使用元素索引,也可以像Deque一樣使用隊列操作。LinkedList每個節點都包含了前一個和後一個節點的引用,因此可以很方便地在其中進行節點的插入、刪除和移動。相比於ArrayList,Li... ...
  • gRPC(gRPC Remote Procedure Call)是由 Google 開發的開源 RPC 框架,它基於 HTTP/2 標準,使用 Protocol Buffers 作為介面定義語言(IDL)。gRPC 提供了一種高效、跨語言、跨平臺的遠程過程調用(RPC)解決方案,被廣泛應用於構建分佈 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...