首页 > 其他分享 > Go 语言进阶与依赖管理

Go 语言进阶与依赖管理

时间:2023-01-19 21:55:23浏览次数:37  
标签:依赖 协程 进阶 int make goroutine chan func Go

Goroutine

在一个函数前加上go关键字就能为一个函数创建一个协程来运行

Go 协程有这种调度机制:
循环并不会等待打印操作执行完再创建下一个协程,而是直接进行下一个循环,立刻创建新协程,一共创建了10个协程。而这10个协程的调度时机又是不确定的

func pr(i int) {
	fmt.Println("goroutine : ", i)
}

func main() {
	for i := 1; i <= 10; i++ {
		go pr(i)
	}
	time.Sleep(time.Second)
}

Channel


Channel创建的方法:

  • ch1 := make(chan int) // 无缓冲通道
  • ch2 := make(chan int, 2) // 有缓冲通道

通过通信共享内存:

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int, 2)

	go func() {
		defer close(ch1)
		for i := 1; i <= 10; i++ {
			ch1 <- i
		}
	}()

	go func() {
		defer close(ch2)
		for i := range ch1 {
			ch2 <- i * i
		}
	}()

	for i := range ch2 {
		println(i)
	}
}

由输出结果可知实现了并发安全
CPU在同一时间只能运行一个任务,我们看起来好像是同时在运行的,这个就叫做并发。而并行则是在同一时刻,执行多个任务。

Lock && WaitGroup

互斥锁:
使用互斥锁能够保证同一时间有且只有一个goroutine进入临界区,其他的goroutine则在等待锁;当互斥锁释放后,等待的goroutine才可以获取锁进入临界区,多个goroutine同时等待一个锁时,唤醒的策略是随机的。

通过暴力方法休眠

var (
	x    int
	lock sync.Mutex
)

func withLock() {
	for i := 1; i <= 2000; i++ {
		lock.Lock()
		x++
		lock.Unlock()
	}
}

func withoutLock() {
	for i := 1; i <= 2000; i++ {
		x++
	}
}
func main() {
	x = 0
	for i := 1; i <= 5; i++ {
		go withLock()
	}
	time.Sleep(time.Second)
	fmt.Println(x)

	x = 0
	for i := 1; i <= 5; i++ {
		go withoutLock()
	}
	time.Sleep(time.Second)
	fmt.Println(x)
}

WaitGroup:

  • add开启协程
  • Done在一个子协程结束后计数器--
  • wait在计数器归零时进行阻塞
var num sync.WaitGroup

func pr(i int) {
	defer num.Done()
	println("Hello ", i)
}

func main() {
	num.Add(10)
	for i := 1; i <= 10; i++ {
		go pr(i)
	}
	num.Wait()
}

标签:依赖,协程,进阶,int,make,goroutine,chan,func,Go
From: https://www.cnblogs.com/Aidan347/p/17062206.html

相关文章