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 ...
随机推荐
- 最新 世纪龙java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.世纪龙等10家互联网公司的校招Offer,因为某些自身原因最终选择了世纪龙.6.7月主要是做系统复习.项目复盘.LeetCo ...
- python 计算文件夹里所有内容的大小总和
计算文件夹里所有内容的大小总和 递归方法 '''计算文件夹的大小''' import os def dir_file_size(path): if os.path.isdir(path): file_ ...
- CNN-2: AlexNet 卷积神经网络模型
1.AlexNet 模型简介 由于受到计算机性能的影响,虽然LeNet在图像分类中取得了较好的成绩,但是并没有引起很多的关注. 知道2012年,Alex等人提出的AlexNet网络在ImageNet大 ...
- Docker下搭建mongodb副本集
背景 有需求需要对mongodb做一个容灾备份.根据官网,发现mongodb最新版本(4.0)已经抛弃了主从模式而采用副本集进行容灾.副本集的优势在于:"有自动故障转移和恢复特性,其任意节点 ...
- PAT甲级 散列题_C++题解
散列 PAT (Advanced Level) Practice 散列题 目录 <算法笔记> 重点摘要 1002 A+B for Polynomials (25) 1009 Product ...
- LC 33. Search in Rotated Sorted Array
问题描述 Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. ...
- python3 字符集的应用
python3的字符集测试 s_test=u"严" print(s_test.encode('gbk')) print([s_test]) #print(s_test[]) #pr ...
- jquery 广告轮播图
轮播图 /*轮播图基本功能: * 1图片切换 * 1.1图片在中间显示 * 1.2图片淡入淡出 * 2左右各有一个按钮 * 2.1点击左按钮,图片切换上一张 * 2.2点击右按钮,图片切换下一张 * ...
- js 颜色随机切换
生成随机颜色 方法1:RGB模式 function randomColor1() { var r=Math.floor(Math.random()*256); var g=Math.floor(Mat ...
- JS 06 bom 框窗_页面_定时任务
BOM(Broswer Object Model) 凡是 window 的属性和方法,均可以省略“window.” 方法: 框窗 1.警告框 window.alert("msg") ...