亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

種族(?) 與互斥體 - 地圖中的數據損壞

種族(?) 與互斥體 - 地圖中的數據損壞

Go
桃花長相依 2022-08-24 10:46:47
在項目中,我想使用緩存來存儲哈希之類的東西。但是,緩存中存儲的值會不時更改為密鑰。通常從密鑰中選取大約 4 個字符:<- Set hash::helloworldtest = abcdef0123456789-> Get hash::helloworldtest = testef0123456789這大致是我的緩存的結構:type node struct {    expires nodeExpiration    value   interface{}}// ...func (c *Cache) Set(key string, value interface{}, expiration time.Duration) {    c.mu.Lock()    c.val[key] = &node{        expires: c.expiration(expiration),        value:   value,    }    // fmt.Println( ... )    c.mu.Unlock()}func (c *Cache) Get(key string) (interface{}, bool) {    c.mu.Lock()    if v, o := c.val[key]; o && v != nil {        if !v.expires.IsExpired() {            // fmt.Println( ... )            c.mu.Unlock()            return v.value, true        }    }    c.mu.Unlock()    return nil, false}// Cache Backendfunc (b *CacheBackend) GetHash(key string) (res string, err error) {    return b.get("hash::" + key)}func (b *CacheBackend) get(key string) (res string, err error) {    if v, ok := b.cache.Get(key); ok {        if s, ok := v.(string); ok {            return s, nil        }        return "", b.errCast    }    return "", nil}// go-fiber Routefunc (s *WebServer) handleGetHashAnywhere(ctx *fiber.Ctx) (err error) {    path := ctx.Params("anywhere")    var res string    if res, err = s.Backend.GetHash(path); err != nil {        return    }    if res == "" {        ctx.Status(404)    } else {        ctx.Status(200)    }    return ctx.SendString(res)}我以前使用過 a,但用 一個 替換了它,認為這可能是問題所在。但與.sync.RWMutexsync.Mutexsync.MutexGet 和 Set 方法在 goroutine 中由 go-fiber 調用,然后返回這些值。有沒有人知道這樣的事情是如何發生的?編輯1:保存而不是工作正常。[]bytestring
查看完整描述

1 回答

?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

該問題在零分配下的文檔中進行了描述。摘錄:

由于纖程針對高性能進行了優化,因此從纖程返回的值。默認情況下,Ctx 不是不可變的,并且將在請求之間重復使用。[...]一旦您從處理程序返回,您從上下文中獲得的任何值都將在將來的請求中重復使用,并將在您的腳下更改。

因此,必須復制上下文值,或者必須在纖程配置中傳遞“不可變”標志。

第一種解決方案:
從讀取值中新建緩沖區并復制其內容

buf := bytes.NewBufferString(ctx.Params("hash"))
hash := string(buf.Bytes())

第二種解決方案:
使用此處描述的內置函數。utils#CopyString(string)

hash := utils.CopyString(ctx.Params("hash"))

第三個解決方案:
不可變的配置標志

cfg := &fiber.Config{Immutable: true}

然后一切正常。


查看完整回答
反對 回復 2022-08-24
  • 1 回答
  • 0 關注
  • 99 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號