Questions - concurrency

Kesa...大约 4 分钟

1. 有缓冲和无缓冲的 Channel 区别

func main() {
	st := time.Now()
	ch := make(chan bool)
	go func ()  {
		time.Sleep(time.Second * 2)
		<-ch
	}()
	ch <- true  // 无缓冲,发送方阻塞直到接收方接收到数据。
	fmt.Printf("cost %.1f s\n", time.Now().Sub(st).Seconds())
	time.Sleep(time.Second * 5)
}
func main() {
	st := time.Now()
	ch := make(chan bool, 2)
	go func ()  {
		time.Sleep(time.Second * 2)
		<-ch
	}()
	ch <- true
	ch <- true // 缓冲区为 2,发送方不阻塞,继续往下执行
	fmt.Printf("cost %.1f s\n", time.Now().Sub(st).Seconds()) // cost 0.0 s
	ch <- true // 缓冲区使用完,发送方阻塞,2s 后接收方接收到数据,释放一个插槽,继续往下执行
	fmt.Printf("cost %.1f s\n", time.Now().Sub(st).Seconds()) // cost 2.0 s
	time.Sleep(time.Second * 5)
}

2. 简述 协程泄露(Goroutine Leak)

Goroutine Leak 只得时 Goroutine 在创建之后无法停止并被回收,最终导致内存泄露与程序崩溃。

常见场景:

 func query() int {
 	ch := make(chan int)
 	for i := 0; i < 1000; i++ {
 		go func() { ch <- 0 }()
 	}
 	return <-ch
 }
 
 func main() {
 	for i := 0; i < 4; i++ {
 		query()
 		fmt.Printf("goroutines: %d\n", runtime.NumGoroutine())
 	}
 }

3. GOMAXPROCS 作用

The GOMAXPROCS variable limits the number of operating system threads that can execute user-level Go code simultaneously. There is no limit to the number of threads that can be blocked in system calls on behalf of Go code; those do not count against the GOMAXPROCS limit.

GOMAXPROCS 限制的是同时执行用户态 Go 代码的操作系统线程的数量,但是对于被系统调用阻塞的线程数量是没有限制的。

GOMAXPROCS 的默认值等于 CPU 的逻辑核数,同一时间,一个核只能绑定一个线程,然后运行被调度的协程。

使用环境变量GOMAXPROCS或函数runtime.GOMAXPROCS设置。

如 GOMAXPROCS 超过 CPU 核心数,因为同时运行的线程最大为 CPU 核心数,此时反而增加线程切换的开销,降低性能。

对于 I/O 密集型应用,可以适当增大该值以提高 I/O 吞吐率。

4. mutex 有几种模式

mutex 有 正常模式 和 饥饿模式:

5. Goroutine 何时发生内存泄露

在Go中内存泄露分为暂时性内存泄露和永久性内存泄露。

暂时性内存泄露

永久性内存泄露

6. Go 的竞争条件

所谓竞态竞争,就是当两个或以上的goroutine访问相同资源时候,对资源进行读/写。

可以用go run -race xx.go来进行检测。

解决方法是,对临界区资源上锁,或者使用原子操作(atomics),原子操作的开销小于上锁。

7. 如果若干个goroutine,有一个panic会怎么做?

有一个panic,那么剩余goroutine也会退出,程序退出。如果不想程序退出,那么必须通过调用 recover() 方法来捕获 panic 并恢复将要崩掉的程序。

8. defer 可以捕获子 goroutine 的 panic 么

不可以,必须在子协程中捕获后进行处理或抛出。

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.2