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 ...
随机推荐
- CenOS 7 防火墙 端口 systemctl 操作项
Centos开放端口 # firewall-cmd --zone=public --add-port=3306/tcp --permanent Centos关闭端口 # firewall-cmd -- ...
- java类加载全过程
引用:http://blog.csdn.net/haluoluo211/article/details/49908463 http://www.cnblogs.com/pengfeiliu/p/442 ...
- json 和对象互相转换
json 和对象互相转换 导入 Jar 包: import com.fasterxml.jackson.databind.ObjectMapper; Maven 地址: <!-- https:/ ...
- [转帖]超详细的PostgreSQL体系结构总结,值得收藏
超详细的PostgreSQL体系结构总结,值得收藏 https://www.toutiao.com/i6715390855772897800/ 原创 波波说运维 2019-07-26 00:03:00 ...
- vim字符匹配
按 : 这个符号进入命令模式后,可以对文本信息进行替换.删除等操作.
- MogileFS表说明
MogileFS大致的表说明如下 checksum:用来存放文件的校验和class:文件分类定义device:主机上的可用设备定义,包括设备可用空间,使用的权重等信息domain:域定义信息file: ...
- [eclipse]UML之AmaterasUML 插件
软件体系结构分析软件设计模式要求给出相应设计模式源码对应的UML类图,在此之前我安装过一种UML插件,可以自动生成一个源码包对应的UML类图,但是重装过系统,所以软件包括eclipse都重新下载了新的 ...
- Qt里的原子操作QAtomicInteger,有挑战性,使用Q_ATOMIC_INT{nn}_IS_SUPPORTED测试系统是否支持
所谓原子操作,即一系列复杂的操作能一气呵成,中间不被其他的操作打断.这在多线程程序中尤其常见,但要实现这种功能,既要考虑程序的良好设计,又要关心特定平台的体系结构和相关编译器对原子特性的支持程度.所以 ...
- C# SHA512和Base64加解密方法
/// <summary> /// Get SHA512 Hash From String /// </summary> /// <param name="or ...
- java 文件上传 下载 总结
首先引入2个jar ![](http://images2017.cnblogs.com/blog/1128666/201711/1128666-20171101145630498-2084371020 ...