教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Go 语言基础——协程(goroutine)&共享内存线程安全

Go 语言基础——协程(goroutine)&共享内存线程安全

发布时间:2023-03-05   编辑:jiaochengji.com
教程集为您提供Go 语言基础——协程(goroutine)&共享内存线程安全等资源,欢迎您收藏本站,我们将为您提供最新的Go 语言基础——协程(goroutine)&共享内存线程安全资源

协程(goroutine)是更轻量级的线程

比Java中的线程效率更高

协程语法
go func() {
   //...
}()

一旦主goroutine中的代码执行完毕,当前的Go程序就会结束运行,无论其他的 goroutine是否已经在运行了。

让主goroutine等待其它 goroutine:
for i := 0; i < 10; i   {
    go func() {
        fmt.Println(i)
    }()
}
time.Sleep(time.Millisecond * 1000)
//goroutine 完成的时间很可能小于设置的等待时间,那么这就会造成多余的等待时间
怎么才能让goroutine执行完后立刻执行下一个goroutine呢?

go语言提供的WaitGroup可以实现这样的功能.

代码改造:

var wg sync.WaitGroup
for i := 0; i < 10; i   {
    wg.Add(1)//每启动一个协程增加一个等待
    go func() {
        fmt.Println(i)
        wg.Done()//告诉协成等待的事务已经完成
    }()
}
/*
这样我们就不用设置等待时间了,但是执行输出的内容是这样的: 3 7 4 8 8 8 9 10 10 10, 很显然这种方式不能保证goroutine拿到唯一整数
*/
如何保证每个线程拿到的数是惟一的?

代码改造:

var wg sync.WaitGroup
for i := 0; i < 10; i   {
    wg.Add(1)//每启动一个协程增加一个等待
    go func(j int) {//把j只是个形参可以任意命名
        fmt.Println(j)
        wg.Done()//告诉协成等待的事务已经完成
    }(i)//把实参i传递给形参j
}
//执行结果:0 2 1 6 3 4 5 8 7 9

我们把i值传递给j,i的变化不会影响j的值,所以输出的结果是唯一的

共享内存线程安全
func TestCounter(t *testing.T) {
    counter := 0
    for i := 0; i < 5000; i   {
        go func() {
            counter  
        }()
    }
    time.Sleep(1 * time.Second)
    t.Logf("counter = %d", counter)
}
//执行结果: 4760 出现了线程安全的问题

和大多数语言一样go也支持加锁保证线程的安全:

func TestCounterWaitGroup(t *testing.T) {
    var mut sync.Mutex//创建锁对象
    var wg sync.WaitGroup
    counter := 0
    for i := 0; i < 5000; i   {
        wg.Add(1)//每启动一个协程增加一个等待
        go func() {
            defer func() {
                mut.Unlock()//释放锁
            }()
            mut.Lock()//开启锁
            counter  
            wg.Done()//告诉协成等待的事务已经完成
        }()
    }
    wg.Wait()//等待协程
    t.Logf("counter = %d", counter)

}

码字不易如果对你有帮助请给个关注

爱技术爱生活 QQ群: 894109590


到此这篇关于“Go 语言基础——协程(goroutine)&amp;共享内存线程安全”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Goroutine并发调度模型深度解析&amp;手撸一个协程池
GO 语言之 Goroutine 原理解析
go 协程
简单理解 Goroutine 是如何工作的
Go语言基础(3)
网页标题随机显示名言js代码
专家教你如何有效的学习Drupal - Drupal问答
Go语言爱好者周刊:第 78 期 — 这道关于 goroutine 的题
探索Golang协程实现——从v1.0开始
golang goroutine 通知_深入golang之---goroutine并发控制与通信

[关闭]
~ ~