Frequently Asked Questions:变量存储位置?Go的原子和并发

197 阅读2分钟

这是我参与更文挑战的第13天,活动详情查看:更文挑战

我怎么知道变量是存在堆上还是栈上?

准确来说,你其实不需要关心变量到底存在什么地方。主要有引用指向某个变量,那么它就一定存在。具体存在什么地方取决于每个语言的实现方式。

变量存在什么地方确实会影响到程序的运行效率。Go编译器会把一个函数中的局部变量放在这个函数的栈中,但是如果编译器无法保证变量在函数执行完毕返回后,还有地方被引用,编译器会把遍历那个放置在垃圾回收堆中来避免悬挂指针错误(dangling pointer errors)。另外如果本地变量很大,这个变量放在堆上比放在栈上更加合理。

在目前编译器的实现中,如果一个变量占据了一个地址(address),就有资格被分配到堆上,但是经过基础的“逃逸分析”,某种情况下,在函数执行完后,变量会重新回到堆上。

correctness n 正确
standpoint 立场

什么操作是原子的?mutexes是怎么样的?

Go的操作原子性详细描述在这个链接中可以看到:golang.org/ref/mem

低级的同步和原始原子操作实现可以使用syncsync/atomic 包。这些包在一些简单任务比如自增或者小规模的互锁等等。

高级的操作,比如并发服务器之间的写作,使用高级的技术能够让程序运行得更好。Go是通过channels来实现的。例如,你可以设计的你程序:只有一个协程在某一个刻处理一块数据,而其他协程是碰不到这些数据的。你可以看原始总结文档:www.youtube.com/watch?v=PAA…

不同程序之间不要通过共享内存数据来通讯,而是要通过通许来共享内存数据。

查看这篇文章了解怎么通过通讯来共享内存golang.org/doc/codewal…

大规模的并发程序也都类似使用这些工具集。