Go语言专题
1. 轻量级线程goroutine和互斥锁的用法
以下代码展示了goroutine的最基本的用法:
package main
func foo() {
n := 1
for {
println("foo:", n)
n = 1
if n > 2 {
break
}
}
}
func bar() {
n := 1
for {
println("bar:", n)
n = 1
if n > 2 {
break
}
}
}
func main() {
go foo()
go bar()
println("Finish!")
}
该代码将foo()和bar()这两个函数当做独立的线程来运行,但是当我们运行该代码的时候没有得到这两个线程的任何输出,如下图所示:
这是因为在这两个线程开始运行之前,主程序就已经运行结束了。为了令这两个线程能够正常运行,我们需要增加一个WaitGroup。修改后的程序如下图所示:
package main
import (
"sync"
)
var wg sync.WaitGroup
func foo() {
defer wg.Done()
n := 1
for {
println("foo:", n)
n = 1
if n > 2 {
break
}
}
}
func bar() {
defer wg.Done()
n := 1
for {
println("bar:", n)
n = 1
if n > 2 {
break
}
}
}
func main() {
wg.Add(2)
go foo()
go bar()
wg.Wait()
println("Finish!")
}
通过增加WaitGroup,我们可以使得这两个线程被正常执行,如下图所示:
但是这样的话,当两个线程访问同一资源的时候,它们之间就可能会发生竞争,从而导致程序的运行结果不正确。比如,考虑如下程序:
package main
import (
"sync"
)
var wg sync.WaitGroup
var counter int
func foo() {
defer wg.Done()
n := 1
for {
counter = 1
n = 1
if n > 10000 {
break
}
}
}
func bar() {
defer wg.Done()
n := 1
for {
counter = 1
n = 1
if n > 10000 {
break
}
}
}
func main() {
counter = 0
wg.Add(2)
go foo()
go bar()
wg.Wait()
println("counter:", counter)
}
该程序的执行结果如下:
在这个程序中,我们预期的输出应该是counter=20000,但是因为foo()和bar()这两个函数之间发生了竞争,所以程序每次运行其结果都可能会发生变化。为了解决这个问题,我们可以给资源counter加一个互斥锁。修改后的代码如下所示:
package main
import (
"sync"
)
var wg sync.WaitGroup
var counter int
var m sync.Mutex
func foo() {
defer wg.Done()
n := 1
for {
m.Lock()
counter = 1
m.Unlock()
n = 1
if n > 10000 {
break
}
}
}
func bar() {
defer wg.Done()
n := 1
for {
m.Lock()
counter = 1
m.Unlock()
n = 1
if n > 10000 {
break
}
}
}
func main() {
counter = 0
wg.Add(2)
go foo()
go bar()
wg.Wait()
println("counter:", counter)
}
以上程序执行结果如下:
2. 定义一个数组,之后将其容量增加1
首先我们可以使用如下程序定义一个容量为10的int型数组:
package main
func main() {
b := make([]int, 10)
for i := 0; i < len(b); i = 1 {
b[i] = i*i
}
println("len:", len(b))
for i := 0; i < len(b); i = 1 {
println(i, b[i])
}
}
其执行结果如下:
现在我们增加以下语句:
b = append(b, make([]int, 1)...)
增加该语句后的程序如下:
package main
func main() {
b := make([]int, 10)
for i := 0; i < len(b); i = 1 {
b[i] = i*i
}
println("original:")
println("len:", len(b))
for i := 0; i < len(b); i = 1 {
println(i, b[i])
}
println("new:")
b = append(b, make([]int, 1)...)
println("len:", len(b))
for i := 0; i < len(b); i = 1 {
println(i, b[i])
}
}
其执行结果如下:
注意,这里我们增加的语句是b = append(b, make([]int, 1)...)
而不是b = append(b, make([]int, 1))
,这里的...
的具体含义目前尚不清楚。
3. dial tcp 172.217.160.113:443: i/o timeout
在我的程序中如下一段代码:
import (
"math"
"runtime"
"sync/atomic"
"time"
"github.com/go-kratos/aegis/pkg/cpu"
"github.com/go-kratos/aegis/pkg/window"
"github.com/go-kratos/aegis/ratelimit"
)
在运行的过程中会提示以下错误:
bbr/bbr.go:9:2: github.com/fsnotify/fsnotify@v1.5.1: Get "https://proxy.golang.org/github.com/fsnotify/fsnotify/@v/v1.5.1.mod": dial tcp 172.217.160.113:443: i/o timeout
bbr/bbr.go:10:2: github.com/fsnotify/fsnotify@v1.5.1: Get "https://proxy.golang.org/github.com/fsnotify/fsnotify/@v/v1.5.1.mod": dial tcp 172.217.160.113:443: i/o timeout
bbr/bbr.go:11:2: github.com/fsnotify/fsnotify@v1.5.1: Get "https://proxy.golang.org/github.com/fsnotify/fsnotify/@v/v1.5.1.mod": dial tcp 172.217.160.113:443: i/o timeout
解决这个问题的方案是在命令行执行以下命令:
go env -w GOPROXY=https://goproxy.cn
之后再次运行该程序就不会提示这个错误了。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfbbjj
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01