指针通过通道丢失

问题描述 投票:0回答:1

这是 Go 代码

package main

import (
    "fmt"
    "math/rand"
)

type MyType struct {
}

func main() {
    chanAdd := make(chan *MyType, 1)
    chanRemove := make(chan *MyType, 1)
    chanGive := make(chan *any, 1)

    foundCount, notFoundCount := .0, .0
    total := .0
    percent := .0

    go func() {
        localStore := make(map[*MyType]bool)
        for {
            <-chanGive
            for i := 0; i < 10; i++ {
                item := new(MyType)
                localStore[item] = true
                chanAdd <- item
            }
            for item, _ := range localStore {
                if rand.Intn(10) > 5 {
                    chanRemove <- item
                    delete(localStore, item)
                }
            }
        }
    }()

    store := make(map[*MyType]bool)

    for {
        select {
        case item := <-chanAdd:
            store[item] = true
        case item := <-chanRemove:
            total++
            if _, found := store[item]; found {
                delete(store, item)
                foundCount++
            } else {
                notFoundCount++
            }
        default:
            if len(chanGive) == 0 {
                chanGive <- new(any)
            }
        }

        if total > 0 {
            percent = foundCount / total * 100
        }
        fmt.Printf("\rFound: %f%%", percent)
    }
}

我们有两个存储指针的映射。一种是 go 例程本地的,另一种仅在主进程中使用。 go 例程通过一个通道发送要存储的指针,并在另一个通道中发送要删除的指针。

主进程检查之前是否已添加了要求删除的指针。然后显示实际找到并删除的指针的百分比。

此代码输出 100% 成功。

但是,如果您更改通道大小,例如 100:

chanAdd := make(chan *MyType, 100)
chanRemove := make(chan *MyType, 100)

然后百分比下降到~90%。 当然,这是一个简化的示例,但我面临着一个更复杂的代码的实际问题。

我搜索了指针在通过通道时到底发生了什么。但我找不到答案。

go run -race

似乎没有检测到竞争条件。我可能错了?

go pointers channel
1个回答
0
投票

写这个简化的例子来发布这个问题对我帮助很大! 事实上,在我给出的示例中,对于较大的通道,有时代码会尝试删除尚未添加到列表中的指针。

© www.soinside.com 2019 - 2024. All rights reserved.