登录
首页 >  Golang >  Go问答

在 Go 中分配指针是原子的吗?

来源:Golang技术栈

时间:2023-04-13 09:05:12 141浏览 收藏

积累知识,胜过积蓄金银!毕竟在##column_title##开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《在 Go 中分配指针是原子的吗?》,就带大家讲解一下golang知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

问题内容

在 Go 中分配指针是原子的吗?

我需要在锁中分配一个指针吗?假设我只想将指针分配给 nil,并希望其他线程能够看到它。我知道在 Java 中我们可以为此使用 volatile,但 Go 中没有 volatile。

正确答案

在 go 中唯一保证是原子的就是sync.atomic中的操作。

所以如果你想确定你要么需要一个锁,例如sync.Mutex ,要么使用一个原子原语。我不建议使用原子原语,因为您必须在使用指针的任何地方都使用它们,而且它们很难正确使用。

使用互斥锁是可以的风格 - 您可以定义一个函数来非常容易地返回当前指针并锁定,例如

import "sync"

var secretPointer *int
var pointerLock sync.Mutex

func CurrentPointer() *int {
    pointerLock.Lock()
    defer pointerLock.Unlock()
    return secretPointer
}

func SetPointer(p *int) {
    pointerLock.Lock()
    secretPointer = p
    pointerLock.Unlock()
}

这些函数将指针的副本返回给它们的客户端,即使主指针更改,该副本也将保持不变。这可能会或可能不会接受,具体取决于您的要求的时间紧迫性。避免任何未定义的行为就足够了——垃圾收集器将确保指针始终保持有效,即使指向的内存不再被您的程序使用。

另一种方法是仅从一个 goroutine 进行指针访问,并使用通道来命令 goroutine 执行操作。这将被认为是更惯用的 go,但可能不完全适合您的应用程序。

更新

这是一个展示如何使用的示例atomic.SetPointer。由于使用unsafe.Pointer. 但是unsafe.Pointer强制转换为空,因此运行时成本很小。

import (
    "fmt"
    "sync/atomic"
    "unsafe"
)

type Struct struct {
    p unsafe.Pointer // some pointer
}

func main() {
    data := 1

    info := Struct{p: unsafe.Pointer(&data)}

    fmt.Printf("info is %d\n", *(*int)(info.p))

    otherData := 2

    atomic.StorePointer(&info.p, unsafe.Pointer(&otherData))

    fmt.Printf("info is %d\n", *(*int)(info.p))

}

今天关于《在 Go 中分配指针是原子的吗?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

声明:本文转载于:Golang技术栈 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表