我应该使用通道还是 sync.Mutex lock()?
should I use a channel or a sync.Mutex lock()?
在执行 go test -race
时,我发现调用 os.Process.Kill, was made before the command started cmd.Start(), I came with to posible solutions, one to use a channel:
package main
import "os/exec"
func main() {
cmd := exec.Command("sleep", "10")
started := make(chan struct{}, 1)
go func() {
<-started
cmd.Process.Kill()
}()
if err := cmd.Start(); err != nil {
panic(err)
}
started <- struct{}{}
cmd.Wait()
}
或使用 lock:
package main
import (
"os/exec"
"sync"
)
func main() {
var lock sync.Mutex
cmd := exec.Command("sleep", "10")
lock.Lock()
if err := cmd.Start(); err != nil {
panic(err)
}
lock.Unlock()
go func() {
cmd.Process.Kill()
}()
cmd.Wait()
}
这两个选项都有效,但想知道什么是最惯用或更好的方法,而主要目标只是防止终止尚未启动的进程。
我建议你使用一个频道,但让我指出一些关于你的代码的事情。
我注意到您使用了缓冲通道,然后先在该通道上发送数据,然后再调用使用该通道的 goroutine。在我看来,最好是:
1) 使用无缓冲通道进行信号传输,尤其是在这种情况下。
2) 让 goroutine 负责启动进程并调用 wait,同时向 main 发出它已启动的信号。
像这样:
package main
import "os/exec"
func main() {
cmd := exec.Command("sleep", "10")
started := make(chan struct{})
go func(cmd *exec.Cmd, signal chan struct{}) {
if err := cmd.Start(); err != nil {
panic(err)
}
started <- struct{}{}
cmd.Wait()
}(cmd, started)
<-started
cmd.Process.Kill()
}
在执行 go test -race
时,我发现调用 os.Process.Kill, was made before the command started cmd.Start(), I came with to posible solutions, one to use a channel:
package main
import "os/exec"
func main() {
cmd := exec.Command("sleep", "10")
started := make(chan struct{}, 1)
go func() {
<-started
cmd.Process.Kill()
}()
if err := cmd.Start(); err != nil {
panic(err)
}
started <- struct{}{}
cmd.Wait()
}
或使用 lock:
package main
import (
"os/exec"
"sync"
)
func main() {
var lock sync.Mutex
cmd := exec.Command("sleep", "10")
lock.Lock()
if err := cmd.Start(); err != nil {
panic(err)
}
lock.Unlock()
go func() {
cmd.Process.Kill()
}()
cmd.Wait()
}
这两个选项都有效,但想知道什么是最惯用或更好的方法,而主要目标只是防止终止尚未启动的进程。
我建议你使用一个频道,但让我指出一些关于你的代码的事情。
我注意到您使用了缓冲通道,然后先在该通道上发送数据,然后再调用使用该通道的 goroutine。在我看来,最好是:
1) 使用无缓冲通道进行信号传输,尤其是在这种情况下。
2) 让 goroutine 负责启动进程并调用 wait,同时向 main 发出它已启动的信号。
像这样:
package main
import "os/exec"
func main() {
cmd := exec.Command("sleep", "10")
started := make(chan struct{})
go func(cmd *exec.Cmd, signal chan struct{}) {
if err := cmd.Start(); err != nil {
panic(err)
}
started <- struct{}{}
cmd.Wait()
}(cmd, started)
<-started
cmd.Process.Kill()
}