对于我的要求之一,我必须创建 N 个 worker go 例程,这些例程将由一个监控例程进行监控。当所有工作程序完成时,监控程序必须结束。我的代码以死锁结尾,请帮忙。
import "fmt"
import "sync"
import "strconv"
func worker(wg *sync.WaitGroup, cs chan string, i int ){
defer wg.Done()
cs<-"worker"+strconv.Itoa(i)
}
func monitorWorker(wg *sync.WaitGroup, cs chan string) {
defer wg.Done()
for i:= range cs {
fmt.Println(i)
}
}
func main() {
wg := &sync.WaitGroup{}
cs := make(chan string)
for i:=0;i<10;i++{
wg.Add(1)
go worker(wg,cs,i)
}
wg.Add(1)
go monitorWorker(wg,cs)
wg.Wait()
}
最佳答案
你的 monitorWorker 永远不会死。当所有工作人员完成后,它会继续等待 cs。这种死锁是因为在 cs 上不会发送任何其他内容,因此 wg 永远不会达到 0。一个可能的解决方法是让监视器在所有工作人员完成后关闭 channel 。如果for循环在main中,则结束循环,从main返回,结束程序。
例如:http://play.golang.org/p/nai7XtTMfr
package main
import (
"fmt"
"strconv"
"sync"
)
func worker(wg *sync.WaitGroup, cs chan string, i int) {
defer wg.Done()
cs <- "worker" + strconv.Itoa(i)
}
func monitorWorker(wg *sync.WaitGroup, cs chan string) {
wg.Wait()
close(cs)
}
func main() {
wg := &sync.WaitGroup{}
cs := make(chan string)
for i := 0; i < 10; i++ {
wg.Add(1)
go worker(wg, cs, i)
}
go monitorWorker(wg, cs)
for i := range cs {
fmt.Println(i)
}
}
编辑:这是对 OP 第一条评论的回答。
您的程序有三个部分需要同步。首先,您的所有工作人员都需要发送数据。然后您的打印循环需要打印该数据。然后你的主函数需要返回从而结束程序。在您的示例中,所有工作人员都发送数据,所有数据都被打印,但消息永远不会发送到 main ,它应该正常返回。
在我的示例中,main 进行打印,而“monitorWorker”只是告诉 main 何时它收到了需要打印的每条数据。这样程序就会优雅地结束,而不是死锁。
如果你坚持打印循环在另一个 goroutine 中,你可以这样做。但是随后需要向 main 发送额外的通信,以便它返回。在下一个示例中,我使用 channel 来确保打印所有数据时主端。
package main
import (
"fmt"
"strconv"
"sync"
)
func worker(wg *sync.WaitGroup, cs chan string, i int) {
defer wg.Done()
cs <- "worker" + strconv.Itoa(i)
}
func monitorWorker(wg *sync.WaitGroup, cs chan string) {
wg.Wait()
close(cs)
}
func printWorker(cs <-chan string, done chan<- bool) {
for i := range cs {
fmt.Println(i)
}
done <- true
}
func main() {
wg := &sync.WaitGroup{}
cs := make(chan string)
for i := 0; i < 10; i++ {
wg.Add(1)
go worker(wg, cs, i)
}
go monitorWorker(wg, cs)
done := make(chan bool, 1)
go printWorker(cs, done)
<-done
}
关于go - 所有 goroutine 都处于休眠状态 - 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19892732/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123
当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
我想为我的Task模型创建一个status属性,该属性将按以下顺序指示它在三部分进度中的位置:打开=>进行中=>完成。它的工作方式类似于亚马逊包裹的交付方式:已订购=>已发货=>已交付。我想知道设置此属性的最佳方法是什么。我可能是错的,但创建三个独立的bool属性似乎有点多余。实现此目标的最佳方法是什么? 最佳答案 Rails4有一个内置的enummacro.它使用单个整数列并映射到键列表。classOrderenumstatus:[:ordered,:shipped,:delivered]end状态映射如下:{ordered:0,
s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成
我们有一个字符串:“”这个正则表达式://i如何从当前字符串中获取所有匹配项? 最佳答案 "".scan(//)参见scan在ruby-docs上 关于ruby-如何遍历Ruby中所有正则表达式匹配的字符串?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6857852/