c04/c04_08
Opened this issue · 7 comments
4.8 学习 Go 协程:如何实现一个协程池? — Go编程时光 1.0.0 documentation
newTask和woker两个方法没看懂,为什么要这么写呢
newTask: 当前无任务执行或信道未满时,启动协程并执行,满了则阻塞直至不满
worker: 第一次启动时执行task,然后从work信道之中取task,取到了之后继续执行,没取到就阻塞。
这里的defer能够生效吗
自己敲了一遍重新理解了一下,这里的worker函数中 defer func() { <-p.sem }() 语句是多余的
1、当有新任务来的时候NewTask,无缓冲work对列没有接受者,所以阻塞;会往有缓冲对列sem里面写一个数据,这时候启动了work创建了work goroutine,且一直for不关闭;这里面启动了一个无缓冲work的消费者;
2、再有新任务来的时候如果work运行,且sem缓冲空间有,会继续往sem中写继续启动work创建一个新的work goroutine
3、再有新任务来work运行中,且sem无缓冲,则阻塞着,这时候是满的work对列在运行
4、有新的任务来,但是sem缓冲满,work运行结束,会发送task到已经启动的work goroutine中去运行
感觉这个例子我对channel理解多了点
struct {} :表示struct类型
struct {}是一种普通数据类型,一个无元素的结构体类型,通常在没有信息存储时使用。
优点是大小为0,不需要内存来存储struct {}类型的值。
struct {} {}:表示struct类型的值,该值也是空。
struct {} {}是一个复合字面量,它构造了一个struct {}类型的值,该值也是空。
我感觉 defer func() { <-p.sem }() 语句不是多余的。
当goroutine crash的时候用于释放sem信号量,可以创建新的goroutine。
因为task是有可能产生异常的。