苏呆呆的博客 苏呆呆的博客
首页
  • C++
  • Java
  • Go
  • 面向对象
  • 设计模式
  • 领域驱动设计
  • Spring
常用工具
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 关于
    • 收藏
GitHub (opens new window)

苏呆呆

一个向往美好生活的笨人。
首页
  • C++
  • Java
  • Go
  • 面向对象
  • 设计模式
  • 领域驱动设计
  • Spring
常用工具
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 关于
    • 收藏
GitHub (opens new window)
  • HelloWorld
  • 基础
  • 控制流
  • 更多类型
  • 方法
  • 并发
    • Go routine
    • 信道
  • 编程语言--golang
su-dd
2023-03-16
目录

并发

# Go routine

Go 程(goroutine)是由 Go 运行时管理的轻量级线程。

go f(x, y, z)
1

会启动一个新的 Go 程并执行

f(x, y, z)
1

f, x, y 和 z 的求值发生在当前的 Go 程中,而 f 的执行发生在新的 Go 程中。

Go 程在相同的地址空间中运行,因此在访问共享的内存时必须进行同步。sync 包提供了这种能力,不过在 Go 中并不经常用到,因为还有其它的办法(见下一页)。

package main

import (
	"fmt"
	"time"
)

func say(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}

func main() {
	go say("world")
	say("hello")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 信道

信道是带有类型的管道,你可以通过它用信道操作符 <- 来发送或者接收值。

ch <- v    // 将 v 发送至信道 ch。
v := <-ch  // 从 ch 接收值并赋予 v。
1
2

(“箭头”就是数据流的方向。)

和映射与切片一样,信道在使用前必须创建:

ch := make(chan int)
1

默认情况下,发送和接收操作在另一端准备好之前都会阻塞。这使得 Go 程可以在没有显式的锁或竞态变量的情况下进行同步。

以下示例对切片中的数进行求和,将任务分配给两个 Go 程。一旦两个 Go 程完成了它们的计算,它就能算出最终的结果。

package main

import "fmt"

func sum(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
	}
	c <- sum // 将和送入 c
}

func main() {
	s := []int{7, 2, 8, -9, 4, 0}

	c := make(chan int)
	go sum(s[:len(s)/2], c)
	go sum(s[len(s)/2:], c)
	x, y := <-c, <-c // 从 c 中接收

	fmt.Println(x, y, x+y)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
编辑 (opens new window)
上次更新: 2023/03/17, 12:22:25
方法

← 方法

最近更新
01
Qt原子操作
03-15
02
方法
03-13
03
HelloWorld
03-13
更多文章>
Theme by Vdoing | Copyright © 2022-2023 daidai | 皖ICP备2023000523号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式