- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在Go中阅读并发性,并且快要结束了!总体而言,这是一本好书。在其中一个示例中,作者正在描述如何模拟请求复制。代码示例是这样的:
func main() {
doWork := func(
done <-chan interface{},
id int,
wg *sync.WaitGroup,
result chan<- int,
) {
started := time.Now()
defer wg.Done()
// Simulate random load
simulatedLoadTime := time.Duration(1*rand.Intn(5)) * time.Second
/** use two separate select blocks because we want to send/receive two different values, the time.After (receive) and the id (send).
/ if they were in the same select block, then we could only use one value at a time, the other will get lost. */
select {
// do not want to return on <-done because we still want to log the time it took
case <-done:
case <-time.After(simulatedLoadTime):
}
select {
case <-done:
case result <- id:
}
took := time.Since(started)
// Display how long handlers would have taken
if took < simulatedLoadTime {
took = simulatedLoadTime
}
fmt.Printf("%v took %v\n", id, took)
}
done := make(chan interface{})
result := make(chan int)
var wg sync.WaitGroup
wg.Add(10)
for i := 0; i < 10; i++ {
go doWork(done, i, &wg, result)
}
firstReturned := <-result
close(done)
wg.Wait()
fmt.Printf("Received an answer from #%v\n", firstReturned)
}
我不明白的那一行是
case <-time.After(simulatedLoadTime)
。为什么在这里?我们何时使用从该 channel 返回的值。该 channel 甚至如何在选择块之外进行通信?无论出于何种原因,该行似乎在同步结果计时方面都非常重要,因为如果我将其替换为
default:
,则结果将不同步。
最佳答案
这已通过评论得到了回答(请参阅mkopriva's comment here),但让我提供“已回答”的版本。
首先,请注意一点:
done := make(chan interface{})
make(chan struct{})
。由于从未发送任何实际值,因此 channel 的类型无关紧要,但是发送空的
struct
值根本不占用空间,而发送空的
interface{}
则需要空间。1
done
channel 已关闭)(指示其他人击败了我们去做所有事情),而不用理会上述任何一项。
done
channel ,其唯一目的是成为close
d,以便从该 channel 接收立即在EOF处返回其缺少零值的零值; done
channel 以终止其余工作进程;和 select {
case <-done:
case <-time.After(simulatedLoadTime):
}
在里面。
select
预先评估其所有替代项。因此,它在开始选择过程之前会评估
done
channel ,但还会调用
time.After()
。然后,
select
等待具有值或在 channel 末尾且因此具有EOF的任何一个,以先到者为准。
done
channel 将不会关闭。此时,所有goroutine将在
done
channel 上阻塞。但是所有goroutine也会调用
time.After
。
time.After
代码启动一个goroutine,该goroutine在一段时间后将在 channel 上发送当前时间。然后,它返回该 channel 。因此,这两个
<-
操作中的至少一个将完成:要么
done
channel 将被关闭,要么被关闭,由于EOF,我们将获得一个零值,或者
time.After
返回的 channel 将有一个发送时间做到这一点,我们将获得这一值(value)。不管我们实际获得哪个值,我们都会将该值放在地板上,但是两个
<-
运算符之一最终将解除阻塞这一事实保证了该goroutine最终将能够继续执行。
done
channel 的关闭或时间的接收。我们不知道这是哪一个,因为我们不知道
done
channel 关闭将花费多长时间,但是时间的上限仍然是传递给
time.After
的持续时间。也就是说,
done
会(最终)发生,或者在我们选择的时间之后,
time.After
部分会发生。其中之一肯定发生。
select {
case <-done:
return
case <-time.After(simulatedLoadTime):
// everything else happens here
}
但是请注意原始代码中的注释:
// do not want to return on <-done because we still want to log ...
return
。
select
。我们将尝试发送ID,但是如果
done
channel 现在已关闭或被关闭,则停止发送。然后,我们将记录并返回。
done
channel 。我们将其用于仅作为集合而存在的 map ,除了它们还将具有预先声明的“仅方便样式”类型。但这完全是另一回事。
done
channel ,
wg *WaitGroup
值和
result
channel ,而不用将它们作为参数。对我来说尚不清楚,为什么作者选择将其编写为可以成为函数的闭包,然后又不理会闭包为我们带来的任何好处。
关于go - 并发和复制请求,time.After()的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65446569/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!