将顺序测试分为4个例程,如果其中一个失败,则终止所有测试
我刚开始阅读golang,请随身携带。 假设我有一个简单的循环,它可以执行像这样的顺序测试。将顺序测试分为4个例程,如果其中一个失败,则终止所有测试
for f := 1; f <= 1000; f++ {
if doTest(f) {
break
}
}
我循环遍历数字范围并对每个数字进行测试。如果测试失败的一个号码,我打破并退出主线程。够简单。
现在,如何在四个或几个例行程序中正确提供测试编号。基本上,我想以4个批次(或任何数量的例程)测试1到1000之间的数字。 我是否创建4个例程从一个通道中读取数据并将数字顺序送入此通道?或者我可以制作4个单独的频道?
还有一个问题。如果其中一个程序未通过测试,我如何停止所有4个程序?我一直在阅读频道上的一些文章,但我不能把这些文章放在一起。
谢谢。
您可以创建一个生产者/消费者系统:https://play.golang.org/p/rks0gB3aDb
func main() {
ch := make(chan int)
clients := 4
// make it buffered, so all clients can fail without hanging
notifyCh := make(chan struct{}, clients)
go produce(100, ch, notifyCh)
var wg sync.WaitGroup
wg.Add(clients)
for i := 0; i < clients; i++ {
go func() {
consumer(ch, notifyCh)
wg.Done()
}()
}
wg.Wait()
}
func consumer(in chan int, notifyCh chan struct{}) {
fmt.Printf("Start consumer\n")
for i := range in {
<-time.After(100 * time.Millisecond)
if i == 42 {
fmt.Printf("%d fails\n", i)
notifyCh <- struct{}{}
return
} else {
fmt.Printf("%d\n", i)
}
}
fmt.Printf("Consumer stopped working\n")
}
func produce(N int, out chan int, notifyCh chan struct{}) {
for i := 0; i < N; i++ {
select {
case out <- i:
case <-notifyCh:
close(out)
return
}
}
close(out)
}
生产者推从0到99数字的渠道,消费者消费直到通道被关闭。主要我们创建4个客户端,并将它们添加到一个waitgroup中,以可靠地检查每个goroutine是否返回。 每个消费者都可以在notifyCh上发信号,生产者停止工作,并且不会生成进一步的号码,因此所有消费者都会在当前号码后返回。
还有一个选项可以创建4个例程,等待所有例程返回,开始下一个4个例程。但是这在等待时增加了相当的开销。
既然你提到的质数,这里有一个非常酷的黄金钛硅分子筛:https://golang.org/doc/play/sieve.go
你是否会建立一个共同的通道或通道每个例程取决于你想要什么。
如果你只想在里面放一些数字(或者更一般的请求),你不关心哪个goroutine服务那个,当然比分享一个频道更好。例如,当你想要第一个250请求由goroutine1服务时,当然你不能共享一个频道。
对于渠道是一个很好的做法,用它作为输入或输出。而发件人如何发送简单的东西,他完成了关闭频道。好的文章是https://blog.golang.org/pipelines
什么是没有提到的问题 - 你是否还需要另一个通道(或通道)或任何其他通信原语来获得结果。这里是最有趣的频道比喂食。
应该发送什么信息 - 它应该每doTest后发送,一个布尔值,或者只是知道,当寄托都做(但这种情况下,既不布尔是没有必要只是关闭通道)?
如果您更喜欢第一次失败的程序。比我更喜欢使用缓冲共享通道来提供数字。不要忘记关闭它,当所有的数字将被喂养。
而另一缓冲瓒让主线程知道,测试完成。它可以是频道,那里你只放置数字,测试失败,或者如果你还想要一个肯定的结果 - 包含数字和结果的结构通道,或从doTest返回的任何其他信息。
有关渠道非常好的文章也http://dave.cheney.net/2014/03/19/channel-axioms
每四位够程可报告故障的(通过发送错误和关闭渠道)。但是,当所有数字通过并且饲料渠道关闭时,问题就变成了应该做的事情。关于这也是不错的文章http://nathanleclaire.com/blog/2014/02/15/how-to-wait-for-all-goroutines-to-finish-executing-before-continuing/
是的,做测试返回布尔值。如果四个程序中的任何一个未通过测试,则所有四个程序都应该终止。这个想法很简单,我只是想知道如何实现它。我想连续为每个数字运行一些工作。范围可以是[1..1000]或[1..1000000000]鉴于范围可能很长,我想在四个并行线程中拆分测试,并以四个块为单位测试数字。问题是如何在go中构造这个以及如果其中一个例程未能通过测试,如何终止所有线程。感谢文章,我会读一读 –
你说的是测试,你不是指我猜测的单元测试吗?我无法想象一个正确的单元测试需要你的手动去例行调度 – blang
不,当然,我不是指单元测试..我的意思是任何返回bool的工作..对不起,如果我说错了。应该可能重写标题。假设我想测试一下这个数字是一个素数还是可以被其他数字整除。真的没关系。 –
看看我的回答,这是我猜你最喜欢的场景。但还有其他选择,但不是干净的IMO。 – blang