Go语言学习笔记-并发,并行,goroutine,channel

本文介绍了程序、进程和线程的概念及关系,阐述了并发和并行的区别。重点讲解了Go语言中的goroutine机制,包括其与OS线程的多对多关系,以及如何创建和同步goroutine。还介绍了channel的定义、创建、操作,以及有缓冲区和无缓冲区通道的区别,最后提及了互斥锁控制共享资源访问。

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

程序:一组二进制数据,不占用系统资源
进程:程序在操作系统上的一次执行过程。系统进行资源分配和调度的独立单位。
线程:进程的一个执行实体,CPU调度分派的基本单位。

个人理解:程序、进程和线程的关系。程序则是生产资料,进程则为工厂,线程就是工厂里的车间。生产资料不经过工厂加工,则无法得出实际产品。工厂的运作实际上就是靠车间的运作,工厂至少要有一个车间才能运作起来,大型工厂可以有多个车间。

并发:同一时间内执行多个任务(同时用微信和两个人聊天)
并行:同一时刻执行多个任务(两个人同时用微信和人聊天)

goroutine:Go语言中的一种机制,概念类似于线程。Go语言运行时(runtime)调度和管理。Go程序会智能地将 goroutine 中的任务合理地分配给每个CPU。

OS线程:操作系统线程,一般都有固定的栈内存(通常2MB)
一个goroutine的栈内存不固定,最小2KB,最大1GB。

OS线程和goroutine之间的关系:

  1. 一个OS线程对应用户态多个goroutine。
  2. go程序可以同时使用多个操作系统线程。
  3. goroutine和OS线程是多对多的关系,即m:n。

在调用函数是在其前面加上“go”关键字,即可为其创建一个goroutine

启动多个goroutine,和使用sync.WaitGroup来实现goroutine同步

var w sync,WaitGroup

func Hello(i int){
	defer w.Done()  //flag, 标记该函数执行结束
	fmt.Println("Hello goroutine",i)
}
func main (){
	for i := 0; i < 10; i++{
		w.Add(1)	//每for循环一次就启动一个goroutine
		go Hello(i)
	}
	w.Wait()//等待Add()登记的goroutine结束
}

run.GOMAXPROCS(n):设置当前程序并发时占用的CPU逻辑核心数。n:CPU核心数。

单纯的奖函数并发执行是没有多大意义的,函数之间的通信才能体现并发函数的意义

channel:通道,是引用类型,空值为nil

定义格式:
var 变量名 chan 元素类型

var ch chan int

创建channel格式:
make(chan 元素类型, [缓冲大小])

ch := make(chan int, 128)

channel的操作

  1. 发送(send):使用“<-”符号。
ch <- 10
  1. 接收(receive):使用“<-”符号。
x := <- ch
  1. 关闭:
close(ch)

channel关闭成功后,读取完数据后返回零值。

channel有缓冲区和无缓冲区的区别

  1. 无缓冲区:也称同步通道,发送方和接收方必须同时进行,否则会阻塞,形成死锁。
  2. 有缓冲区:通道有容量存放元素,可以有效解决无缓冲区通道阻塞问题。
var w sync.WaitGroup

func receive(ch chan int) {
	defer w.Done()
	x := <-ch
	fmt.Println("receive secceeded", x)
}

func main() {
	ch := make(chan int)
	for i := 0; i < 10; i++ {
		w.Add(1)
		go receive(ch)
		ch <- i
	}
	w.Wait()
	close(ch)
}

无缓冲区通道,必须先做好接收准备,才能发送,不然会形成阻塞

单向通道:我们可以限制通道(只能发送或者接收)

func counter(out chan<- int) {
	for i := 0; i < 100; i++ {
		out <- i
	}
	close(out)
}

func squarer(out chan<- int, in <-chan int) {
	for i := range in {
		out <- i * i
	}
	close(out)
}
func printer(in <-chan int) {
	for i := range in {
		fmt.Println(i)
	}
}

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int)
	go counter(ch1)
	go squarer(ch2, ch1)
	printer(ch2)
}

互斥锁:一种常用的控制共享资源访问的方法,它能够保证同时只有一个goroutine可以访问共享资源

var lock sync.Mutex 
func add(){
		for i := 0; i < 5000; i++ {
		lock.Lock() // 加锁
		x = x + 1
		lock.Unlock() // 解锁
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值