golang开启协程代码是

发布时间:2024-12-23 01:51:24

Go语言是一门静态编译型的开源编程语言,它拥有并发编程的特性,其中最重要的就是协程。协程(Goroutine)是Go语言中轻量级线程的概念,它与传统的线程有着明显的区别,协程可以在代码中以简单的方式创建和调度,并且能够高效地完成并发任务。接下来,我将介绍如何在Go语言中开启协程。

使用go关键字创建协程

在Go语言中,我们可以使用go关键字创建协程。使用go关键字创建的函数将会在一个新的协程中执行,而不会阻塞当前的主线程。

示例代码:

func main() {
    // 主线程
    fmt.Println("Hello, ")

    // 开启一个协程
    go func() {
        // 在协程中执行的代码
        fmt.Println("World!")
    }()

    // 等待协程执行结束
    time.Sleep(time.Second)

    // 主线程
    fmt.Println("Golang")
}

在上面的示例代码中,我们使用go关键字开启了一个协程,该协程会在独立的线程中执行fmt.Println("World!")的代码。在主线程中,我们先输出"Hello, ",然后等待1秒钟,最后输出"Golang"。

协程的调度与同步

在Go语言中,协程的调度由Go语言运行时系统(Goroutine scheduler)负责。Goroutine scheduler会根据一定的规则,自动地将协程分配到合适的线程上运行,并在需要的时候进行调度切换。这种自动调度的机制使得编写并发代码变得更加简单。

当一个协程需要等待其他协程的执行结果时,我们可以使用sync包提供的wait group(WaitGroup)来实现协程的同步。

示例代码:

func main() {
    var wg sync.WaitGroup

    // 定义一个计数器,用于记录需要等待的协程数量
    wg.Add(2)

    // 第一个协程
    go func() {
        defer wg.Done()

        // 在协程中执行的代码
        fmt.Println("Hello, ")
    }()

    // 第二个协程
    go func() {
        defer wg.Done()

        // 在协程中执行的代码
        fmt.Println("World!")
    }()

    // 等待所有协程执行结束
    wg.Wait()

    // 主线程
    fmt.Println("Golang")
}

在上面的示例代码中,我们使用sync包提供的WaitGroup来实现了协程的同步。这里定义了一个计数器,初始值为2,表示需要等待两个协程执行结束。在每个协程的末尾,我们都调用了wg.Done()方法来通知计数器减一。主线程调用wg.Wait()方法来等待所有协程执行结束,并在所有协程执行完毕后输出"Golang"。

协程的并发控制

在实际的开发中,我们有时需要对协程进行更细粒度的控制,比如限制最大并发数量、实现协程的优先级等。Go语言提供了一个内置的包sync/atomic来解决这类问题。

示例代码:

func main() {
    var counter int32

    // 定义一个计数器,用于限制最大并发数量为5
    sem := make(chan struct{}, 5)

    // 循环创建100个协程
    for i := 0; i < 100; i++ {
        sem <- struct{}{} // 协程计数加1

        go func() {
            defer func() {
                <-sem // 协程计数减1
            }()

            atomic.AddInt32(&counter, 1) // 对counter原子加1操作

            // 在协程中执行的业务代码
            // ...

            atomic.AddInt32(&counter, -1) // 对counter原子减1操作
        }()
    }

    // 等待所有协程执行结束
    for i := 0; i < cap(sem); i++ {
        sem <- struct{}{}
    }

    // 输出计数器的值
    fmt.Println("Counter:", atomic.LoadInt32(&counter))
}

在上面的示例代码中,我们使用了一个无缓冲的通道(chan struct{})来限制协程的并发数量为5。通过循环创建100个协程,并在每个协程开始前向通道发送一个信号,当通道中的元素满时,再创建的协程将会被阻塞,从而达到控制并发数量的目的。在协程的业务代码中,我们使用了sync/atomic包提供的原子操作函数来对counter变量进行原子操作,确保操作的完整性。

相关推荐