goroutine 修改全局变量无效问题
原文:https://studygolang.com/topics/7050
go修改全局变量的问题
测试 goroutine 修改全局变量,有x y 两个全局函数,分别在两个 goroutine f1() 和 f2() 中修改(f1()修改x,f2()修改y),f2() 只多了一行sleep,为什么最终主 goroutine 打印y时,y的值一直是0?? 代码如下
package main import (
"fmt"
"runtime"
"time"
) var x, y int func main() {
runtime.GOMAXPROCS(3)
go f1()
go f2()
for {
time.Sleep(time.Second * 1)
fmt.Println("x:", x, "y", y)
}
} func f1() {
for {
x = x + 1
time.Sleep(time.Second * 1)
}
} func f2() {
for {
y = y + 1
}
}
结果:

我的理解是这样的,不知道是否合理。 为了效率,对内存的写入一般会在每一个处理器中缓冲,并在必要时一起flush到主存。而f2没有Sleep,导致一直没有时间片去flush到主存,f1有Sleep,就会flush到主存,所以x值会变化,y的值没变化。
如果runtime.GOMAXPROCS(1),都不会有打印信息出来。被f2独占
可以这样修改,就会变化
package main
import (
"fmt"
"runtime"
"time"
)
var x, y int
func main() {
fmt.Println(runtime.NumCPU())
runtime.GOMAXPROCS(3)
go f1(&x)
go f2(&y)
for {
time.Sleep(time.Second * 1)
fmt.Println("x:", x, "y", y)
}
}
func f1(x *int) {
for {
*x = *x + 1
time.Sleep(time.Second * 1)
}
}
func f2(y *int) {
for {
*y = *y + 1
}
}
1楼 @darren3126 对的,我觉得应该是这样,f1 和 f2 如果都不sleep 的话,相当于分别都独占了M,没有机会写主存 </br>我也测试过,如果是传址的话,值确实会被修改,感谢大神~
这完全是为了安全,如果你想改变全局变量,可以把它塞到chan里面,要在通信里共享内存,大概是这么理解的,不然所有协程一块去写同一块内存,不加锁还,很容易写花的
package main import (
"fmt"
"runtime"
"time"
) var x, y int func main() {
fmt.Println(runtime.NumCPU())
runtime.GOMAXPROCS(3)
x = 100
y = 33
go f1(&x)
go f2(&y)
for {
time.Sleep(time.Second * 1)
fmt.Println("x:", x, "y", y)
}
} func f1(x *int) {
for {
*x = *x + 1
time.Sleep(time.Second * 1)
}
} func f2(y *int) {
for {
*y = *y + 1
}
}
goroutine 修改全局变量无效问题的更多相关文章
- global关键字修改全局变量
#我们知道全局变量在函数外部,强烈建议不要在函数内部修改全局变量,正常情况下,在函数内部改变全局变量并不影响全局变量的值,举例如下 count = 5 >>> def myfun() ...
- win7 Host文件修改后无效的解决办法
win7 Host文件修改后无效的解决办法 正常情况下hosts文件随时修改随时生效,如果出现修改后不生效的情况,首先确定文件是ascii编码,以windows格式为换行符,然后依次采用如下方法 1 ...
- iOS 使用xib定义一个View,修改frame无效问题解决
遇到过好多次使用自定义view,修改frame无效问题, 之前都是放弃xib,直接手写,发现手写简单的还行,复杂的UI就坑逼了.所以还是需要用到可视化编辑的xib. 整理一下,自己备忘也供iOS开发的 ...
- kali linux 2018.2 mysql密码修改后无效,外部无法连接问题。
kali linux 2018.2 mysql密码修改后无效,外部无法连接问题 Kali Linux 2018.2 默认MySQL数据库是mariadb,可能和MySQL有些细微的变化,只需要做如下处 ...
- Ajax修改全局变量问题解决方法(Zepto版)
前两天项目遇到一个用ajax修改全局变量的案例,一开始无法给这个全局变量修改赋值,在网上查了一下,解决如下: 修改前: var word=1; $.ajax({ url:"myJSON.js ...
- JavaScript函数内部修改全局变量的问题【一道面试题】
JavaScript函数内部修改全局变量的问题 今天 10:44梵天莲华 | 浏览 23 次 Javascript编程语言函数 修改标签 代码如下,为什么加了 function a(){};这个函数 ...
- 在函数中修改全局变量的值,需要加global关键字
一.引用 使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字.如: #! /usr/bin/python a = 1 b = [2, 3] def func(): if ...
- Host文件修改后无效的解决办法
什么是hosts文件? 简单的说,hosts文件是用于本地dns服务(相关主题:什么是DNS缓存,如何清除DNS缓存?)的,采用ip 域名的格式写在一个文本文件当中,Hosts是一个没有扩展名的系统文 ...
- 函数中不能对全局变量进行修改,想要修改全局变量需要在变量前面加global
# def change_name(name):# global school # school = "Mage Linux"# print(&quo ...
随机推荐
- Asp.net SignalR 实现服务端消息实时推送到所有Web端
ASP .NET SignalR是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.实际上 Asp.net SignalR 2 实现 服务端消息推送到Web端, 更加 ...
- 终端、虚拟终端、shell、控制台、tty的区别
终端与控制台的区别? 最近开始接触Linux,终端.虚拟终端.shell.控制台.tty等概念让我很混乱,有必要认识清楚. 今天看到有人问终端和控制台的区别,而且这个问题比较有普遍性,因此想抽出一点时 ...
- Python异常 --Python
一.常见的异常类型 FileNotFoundError:找不到指定文件的异常 NameError:未声明或者未初始化对象 BaseException:所有异常的基类 二.异常处理语句 1.try... ...
- Java使用icepdf转高清图片
<dependency> <groupId>org.icepdf.os</groupId> <artifactId>icepdf-core</ar ...
- chapter01图像基本操作
刚刚开始学习opencv,来记录一下自己的学习笔记,也向各位大牛虚心求教 一.图片的基本知识 只要是彩色的图片都有三个颜色通道,即RGB,用三个矩阵来表示. 三个矩阵的同一个坐标位置上的数值描述的是一 ...
- 分布式缓存 - hash环/一致性hash
一 引言 当前memcached,redis这类分布式kv缓存已经非常普遍.我们知道memcached的分布式其实是一种"伪分布式",也就是它的服务器节点之间其实是无关联的,之间没 ...
- Java Socket 的工作机制
转载,请加上原文链接: 目录 socket 对象的创建时间 socket 通信可能会造成死锁 socket 对象的创建时间 这里需要一点TCP的知识, TCP状态分析请看 --> TCP转态转换 ...
- final关键字、多态 (札记)
目录 protected fianl 子父类中同名的 private 方法 java中的前期绑定 免疫多态 谁先被执行,构造器 还是 初始化? 协变返回类型 <Thinking in java& ...
- 2019php面试大全
一 .PHP基础部分 1.PHP语言的一大优势是跨平台,什么是跨平台? PHP的运行环境最优搭配为Apache+MySQL+PHP,此运行环境可以在不同操作系统(例如windows.Linux等)上配 ...
- python学习--13 基本数据类型 2
接上次补充: s = "username\temail\tpassword\naaa\taa@qq.com\t123\nusername\temail\tpassword\naaa\taa@ ...