在 函式 teststoptimeupdate() 中,有這樣一句**,是存放在每乙個分類下面的 書籍,然後 key 為書籍的分類名,具體的 元素 int 為 預設的分頁碼,這樣就達到 每一類 下面 每次都能抓取 新的書籍內容。
make
(map
[string][
]int
)但是 在**中 有 對這個分頁map 有讀和寫 操作
= sliceint
......[1
:len)]
表面上,程式是執行的通,但是在,多個goroutine 當中,併發執行就產生 fatal error:concurrent map read and map write的錯誤 ,也就是併發 讀寫錯誤,
其原因是 map 本身是引用型別 ,在呼叫傳遞 引數時,多個goroutine,就會產生資源競爭情況,因此 最為簡單暴力的方式 是 加鎖 對,就是那個sync.mutex 互斥鎖。
var sm sync.mutex
for ii, vv :=
range urls
)inte***ce()
//----------------------
//任務完成的定時器
iflen)==
0)insmap[
"instruction"]=
"stopticker"
insmap[
"data"
]= cdname
fmt.
println
("------------------定時器:"
, tuname,
"已經完成抓取-----------"
)return insmap
}else[1
:len)]
} fmt.
println
(vv)
fmt.
println
("一共有多少個goroutine:"
,runtime.
numgoroutine()
)return
nil}
接下來 就是加快 定時器的 執行速度。
下面把 cyt := time.duration(
otheroper.randint64(1, 3, true)) * time.nanosecond
引數 從秒變為 nanosecond ,然後max 的隨機數範圍 也調到最小
,然後把 分頁頁碼的max 改為100000,
當然 使用這種方式,的確可以解決問題,但是此時的你可能會直接想到執行效率 問題,沒錯,你想的是的對,
這裡除了這種方式以外,也可以使用sync.map來替代 map和sync.mutex這種組合方式
func
teststoptimeupdate()
sliceint :=
make([
]int,0
) max :=
100for i :=
0; i < max; i++
//var sm sync.mutex
var smap sync.map
for ii, vv :=
range urls
)inte***ce
()//任務完成的定時器
si,_:= smap.
load
(tuname)
si2:=si.([
]int)if
len(si2)==0
) insmap[
"instruction"]=
"stopticker"
insmap[
"data"
]= cdname
fmt.
println
("------------------定時器:"
, tuname,
"已經完成抓取-----------"
)return insmap
}else
smap.
store
(tuname, si2[1:
len(si2)])
} fmt.
println
(vv)
return
nil}
cyt := time.
duration
( otheroper.
randint64(1
,3,true))
* time.nanosecond
tu1 := timerupdate.
createexcutu
(tuname,
1, cyt, args)
ts =
(ts, tu1)
} dispatch.
gorun
(dispatch.
goworkernum(50
), ts...
)}
同時也可以摒棄map 這種方式,來傳遞下標值,從而不使用互斥鎖,
好了,感謝你讀到這裡,下個月,我會繼續 加入定時器的功能
1 新增優先順序任務處理功能,
2 根據任務的數量,自動來設定worker go 的數量,
3 以及 對整個更新器的執行效率的優化,
Redis在高併發下存在的問題
描述 在某些特定環境下,無論是先更新redis還是更新資料庫,兩者的資料都有可能不一致。解決方案1 雙寫模式 解決方案2 失效模式 最終解決方案 無論是雙寫模式還是失效模式,都會導致快取的不一致問題。即多個例項同時更新會出事,怎麼辦?如果是使用者緯度資料 訂單資料 使用者資料 這種併發機率非常小,不...
goland在web中存在的問題
官方文件中明確指出,slice 切片 的零值是 nil,在沒有明確初始化的情況下這是顯而易見的,任何 go 開發者應該都知道才對。但是對於 goland 而言,宣告並直接初始化的空 slice 和宣告不初始化 slice 是一回事。為什麼這麼說呢?如果你在 goland 中寫入以下兩句 var sl...
在vscode中go編碼發生的問題整理
1 配置golang的源。go env w goproxy 2 windows平台按下ctrl shift p,mac平台按command shift p,這個時候vs code介面會彈出乙個輸入框 3 我們在這個輸入框中輸入 go install,下面會自動搜尋相關命令,我們選擇go instal...