这是我正在使用的Golang程序,目的只是为了使我的概念正确。当我运行程序时,它陷入了僵局,我不明白为什么?请任何人指出出了什么问题?
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
numOfGoRoutines := 10
wg.Add(numOfGoRoutines)
ch := make(chan int, numOfGoRoutines)
for i := 0; i < numOfGoRoutines; i++ {
a := i
go sqr(ch, a, wg)
}
wg.Wait()
fmt.Println("After WAIT")
close(ch)
var res int
for i := range ch {
res += i
}
ch = nil
fmt.Println("result = ", res)
}
func sqr(ch chan int, val int, wg sync.WaitGroup) {
fmt.Println("go - ", val)
s := val * val
ch <- s
wg.Done()
}
输出为:
warning: GOPATH set to GOROOT (C:\\Go) has no effect
go - 9
go - 0
go - 1
go - 2
go - 3
go - 4
go - 5
go - 6
go - 7
go - 8
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x5bcabc)
C:/Go/src/runtime/sema.go:47 +0x2d
sync.(*WaitGroup).Wait(0x5bcab0)
C:/Go/src/sync/waitgroup.go:127 +0xbb
main.main()
C:/demo/go-work/main.go:20 +0xdf
exit status 2
问题是您要将传递sync.WaitGroup
给goroutines 的副本,而不是引用(即指针):
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
numOfGoRoutines := 10
wg.Add(numOfGoRoutines)
ch := make(chan int, numOfGoRoutines)
for i := 0; i < numOfGoRoutines; i++ {
a := i
go sqr(ch, a, &wg)
}
wg.Wait()
fmt.Println("After WAIT")
close(ch)
var res int
for i := range ch {
res += i
}
ch = nil
fmt.Println("result = ", res)
}
func sqr(ch chan int, val int, wg *sync.WaitGroup) {
fmt.Println("go - ", val)
s := val * val
ch <- s
wg.Done()
}
另外,由于wg
是全局变量,您可以完全删除该参数:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
numOfGoRoutines := 10
wg.Add(numOfGoRoutines)
ch := make(chan int, numOfGoRoutines)
for i := 0; i < numOfGoRoutines; i++ {
a := i
go sqr(ch, a)
}
wg.Wait()
fmt.Println("After WAIT")
close(ch)
var res int
for i := range ch {
res += i
}
ch = nil
fmt.Println("result = ", res)
}
func sqr(ch chan int, val int) {
fmt.Println("go - ", val)
s := val * val
ch <- s
wg.Done()
}
问题内容: 我正在尝试了解Go语言。我试图创建两个goroutine,使用两个通道将它们之间的流链接起来: 如预期的那样,此代码将输出: 直到主要功能退出。 但是,如果我将另一个值从main发送到其中一个通道,则会突然阻塞: 它输出 然后阻塞,直到主体结束。 发送给c1的值“ 2”到达第一个goroutie,后者将其发送给c2,但是第二个goroutine从不接收。 (在此示例中,使用大小为1(c
第3章 陷入,中断和驱动程序 运行进程时,cpu 一直处于一个大循环中:取指,更新 PC,执行,取指……。但有些情况下用户程序需要进入内核,而不是执行下一条用户指令。这些情况包括设备信号的发出、用户程序的非法操作(例如引用一个找不到页表项的虚拟地址)。处理这些情况面临三大挑战:1)内核必须使处理器能够从用户态转换到内核态(并且再转换回用户态)2)内核和设备必须协调好他们并行的活动。3)内核必须知道
僵尸进程 当一个进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态。 一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。 理解了孤儿进程和僵尸进程,我们临时加了守护进程这一小节,守护进程就是后台进程吗?没那么简单。
学习任何知识之前肯定要对这个知识有一个简单的了解,当然学习 Go 语言也一样,这个小节我们就来简单认识下 Go 语言,了解下 Go 语言的来龙去脉。
问题内容: 我在前台启动了我的程序(守护程序),然后用杀死了它,但剩下一个僵尸,无法用杀死它。如何杀死僵尸进程? 如果僵尸是一个死进程(已被杀死),我如何将其从输出中删除? 问题答案: 僵尸已经死了,所以您无法杀死它。要清理僵尸,必须等待其父级等待,因此杀死父级应该可以消除僵尸。(父对象死后,僵尸将被pid 1继承,而pid 1将等待该僵尸并清除其在进程表中的条目。)如果守护程序正在生成成为僵尸的
问题内容: 我在Go中有一个应用程序,它可以重新路由二进制文件的STDIN和STDOUT,然后运行它们。简而言之,我正在做: 我注意到,只要在运行命令A时退出命令B的进程,它就会在进程表中变成僵尸进程。 这是一个例子: 如果commandB仍在运行时退出,为什么commandB会变成僵尸?我在Ubuntu 14上运行Go 1.5。 问题答案: 当某个进程退出时,无论正在运行什么其他进程,它 总是