Golang goroutine

本文介绍了Go语言中goroutine的基本概念,通过示例展示了如何使用goroutine并发执行任务,以及sync.WaitGroup在控制并发流程中的关键作用。重点讲解了GOMAXPROCS的设置和WaitGroup的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Golang并发介绍

image-20220501140959538

操作系统会在物理处理器上调度线程来运行,而 Go 语言的运行时会在逻辑处理器上调度goroutine来运行。每个逻辑处理器都分别绑定到单个操作系统线程。这些逻辑处理器会用于执行所有被创建的goroutine。即便只有一个逻辑处理器,Go也可以以神奇的效率和性能,并发调度无数个goroutine。

image-20220501141154791

goroutine示例

package main

import (
	"fmt"
	"runtime"
	"sync"
)

func main() {
	// 分配一个逻辑处理器给调度器使用
	runtime.GOMAXPROCS(1)
	// runtime.GOMAXPROCS(runtime.NumCPU())

	// wg 用来等待程序完成
	// 计数加 2,表示要等待两个 goroutine
	var wg sync.WaitGroup
	wg.Add(2)

	fmt.Println("Start Goroutines")

	// 声明一个匿名函数,并创建一个 goroutine
	go func() {
		// 在函数退出时调用 Done 来通知 main 函数工作已完成
		defer wg.Done()

		// 显示字母表三次
		for count := 0; count < 3; count++ {
			for char := 'a'; char < 'a'+26; char++ {
				fmt.Printf("%c ", char)
			}
		}
	}()
	// 声明一个匿名函数,并创建一个 goroutine
	go func() {
		// 在函数退出时调用 Done 来通知 main 函数工作已完成
		defer wg.Done()

		// 显示字母表三次
		for count := 0; count < 3; count++ {
			for char := 'A'; char < 'A'+26; char++ {
				fmt.Printf("%c ", char)
			}
		}
	}()

	// 等待 goroutine 结束
	fmt.Println("Waiting To Finish")
	wg.Wait()

	fmt.Println("\nTerminating Program")
}

Start Goroutines
Waiting To Finish
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N 
O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b 
c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p 

我们以用go关键字并且以匿名函数形式创建了两个goroutine,让他们并发运行,分别打印大写字母表和小写字母表三次。打印大写字母表的goroutine率先抢到了逻辑处理器使用权,并且在切换前就已经打印完毕,所以我们没有看到大小写字母交替出现的情况。

runtime.GOMAXPROCS(1)

这个函数允许程序更改调度器可以使用的逻辑处理器的数量,给这个函数传入 1,是通知调度器只能为该程序使用一个逻辑处理器。

// wg 用来等待程序完成
// 计数加 2,表示要等待两个 goroutine
var wg sync.WaitGroup
wg.Add(2)

// 声明一个匿名函数,并创建一个 goroutine
go func() {
    // 在函数退出时调用 Done 来通知 main 函数工作已完成
    defer wg.Done()
	/*...*/
    }
}()

// 等待 goroutine 结束
wg.Wait()

WaitGroup 是一个计数信号量,可以用来记录并维护运行的 goroutine。如果 WaitGroup 的值大于 0,Wait 方法就会阻塞。

当某个goroutine完成时,会调用wg.Done()表示函数完成,wg信号量减少1,直到wg == 0,并最终释放main函数,让它不再等待,即不再阻塞于wg.Wait()处。

关键词defer会修改函数调用时机,可在函数结束前调用相应函数。在网络编程中关闭一些套接字中会很方便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值