从非 chan 类型接收 *bool
Receive from non-chan type *bool
我想守护我的应用程序,但我有一个大问题。我使用的频道类型为 chan struct{}
。
但是,使用包getopt(标志包),我的标志是* bool类型,所以我不知道如何修改我的应用程序。
bool 类型的频道还不够。我确定有一个我不明白的概念。我附上代码:
package main
import (
"os"
"syscall"
"time"
"github.com/pborman/getopt/v2"
"github.com/sevlyar/go-daemon"
)
var (
done = make(chan struct{})
optQuit = make(chan struct{})
optRun = make(chan struct{})
)
func TermHandler(sig os.Signal) error {
optQuit <- struct{}{}
if sig == syscall.SIGQUIT {
<-done
}
return nil
}
func main() {
optHelp := getopt.BoolLong("help", 'h', "Help")
optQuit := getopt.BoolLong("quit", 0, "Help")
optRun := getopt.BoolLong("run", 'r', "Help")
if *optHelp {
getopt.Usage()
os.Exit(0)
}
// Create pid file
cntxt := &daemon.Context{
PidFileName: "/var/run/myapp.pid",
PidFilePerm: 0644,
WorkDir: "./",
Umask: 027,
Args: []string{"[Z]"},
}
if len(daemon.ActiveFlags()) > 0 {
d, _ := cntxt.Search()
daemon.SendCommands(d)
return
}
d, err := cntxt.Reborn()
if d != nil {
return
}
if err != nil {
os.Exit(1)
}
defer cntxt.Release()
// Define ticker
ticker := time.NewTicker(time.Second)
myapp := true
// Loop
for myapp {
select {
// Case sleep
case <- ticker.C:
time.Sleep(time.Second)
// Case QUIT
case <- optQuit:
done <- struct{}{}
myapp = false
ticker.Stop()
os.Exit(0)
// Case RUN
case <- optRun:
// Executes a goroutine...
}
}
}
使用 go install
,我可以看到这个错误:
./main.go:72: invalid operation: <-optQuit (receive from non-chan type *bool)
./main.go:79: invalid operation: <-optRun (receive from non-chan type *bool)
我不知道应该如何修改通道(完成,struct{} 类型的 optQuit),以解决这个...
P.S.: 我给你看一个我做的例子。它 运行 作为守护进程,每分钟执行函数 Writer()。
之后,如果您键入 zdaemon -z quit
,应用程序将正常关闭。你可以 运行 它在你的机器上:
主函数中的这两行隐藏了全局变量声明:
optQuit := getopt.BoolLong("quit", 0, "Help")
optRun := getopt.BoolLong("run", 'r', "Help")
如果你只使用它们,为了获得良好的用法,为什么不创建一个用法函数
你自己?
如果您坚持使用 getopt
只是为了创建一个用法,请执行
_ = getopt.BoolLong("quit", 0, "Help")
_ = getopt.BoolLong("run", 'r', "Help")
相反。
您还需要在使用 *optHelp
之前调用 getopt.Parse()
。
生成的消息
Usage: test [-hr] [--quit] [parameters ...]
-h, --help Help
--quit Help
-r, --run Help
似乎没什么帮助。为什么不直接做
fmt.Printf(`
Usage: test
This program will start a daemon service, which you can use like this ...
`)
您全局定义 optQuit = make(chan struct{})
,然后在 main:optQuit := getopt.BoolLong("quit", 0, "Help")
中隐藏它。
所以主要的 optQuit 是 bool
,而不是 chan
删除 main 中的这两行:
optQuit := getopt.BoolLong("quit", 0, "Help")
optRun := getopt.BoolLong("run", 'r', "Help")
我想守护我的应用程序,但我有一个大问题。我使用的频道类型为 chan struct{}
。
但是,使用包getopt(标志包),我的标志是* bool类型,所以我不知道如何修改我的应用程序。
bool 类型的频道还不够。我确定有一个我不明白的概念。我附上代码:
package main
import (
"os"
"syscall"
"time"
"github.com/pborman/getopt/v2"
"github.com/sevlyar/go-daemon"
)
var (
done = make(chan struct{})
optQuit = make(chan struct{})
optRun = make(chan struct{})
)
func TermHandler(sig os.Signal) error {
optQuit <- struct{}{}
if sig == syscall.SIGQUIT {
<-done
}
return nil
}
func main() {
optHelp := getopt.BoolLong("help", 'h', "Help")
optQuit := getopt.BoolLong("quit", 0, "Help")
optRun := getopt.BoolLong("run", 'r', "Help")
if *optHelp {
getopt.Usage()
os.Exit(0)
}
// Create pid file
cntxt := &daemon.Context{
PidFileName: "/var/run/myapp.pid",
PidFilePerm: 0644,
WorkDir: "./",
Umask: 027,
Args: []string{"[Z]"},
}
if len(daemon.ActiveFlags()) > 0 {
d, _ := cntxt.Search()
daemon.SendCommands(d)
return
}
d, err := cntxt.Reborn()
if d != nil {
return
}
if err != nil {
os.Exit(1)
}
defer cntxt.Release()
// Define ticker
ticker := time.NewTicker(time.Second)
myapp := true
// Loop
for myapp {
select {
// Case sleep
case <- ticker.C:
time.Sleep(time.Second)
// Case QUIT
case <- optQuit:
done <- struct{}{}
myapp = false
ticker.Stop()
os.Exit(0)
// Case RUN
case <- optRun:
// Executes a goroutine...
}
}
}
使用 go install
,我可以看到这个错误:
./main.go:72: invalid operation: <-optQuit (receive from non-chan type *bool)
./main.go:79: invalid operation: <-optRun (receive from non-chan type *bool)
我不知道应该如何修改通道(完成,struct{} 类型的 optQuit),以解决这个...
P.S.: 我给你看一个我做的例子。它 运行 作为守护进程,每分钟执行函数 Writer()。
之后,如果您键入 zdaemon -z quit
,应用程序将正常关闭。你可以 运行 它在你的机器上:
主函数中的这两行隐藏了全局变量声明:
optQuit := getopt.BoolLong("quit", 0, "Help")
optRun := getopt.BoolLong("run", 'r', "Help")
如果你只使用它们,为了获得良好的用法,为什么不创建一个用法函数 你自己?
如果您坚持使用 getopt
只是为了创建一个用法,请执行
_ = getopt.BoolLong("quit", 0, "Help")
_ = getopt.BoolLong("run", 'r', "Help")
相反。
您还需要在使用 *optHelp
之前调用 getopt.Parse()
。
生成的消息
Usage: test [-hr] [--quit] [parameters ...]
-h, --help Help
--quit Help
-r, --run Help
似乎没什么帮助。为什么不直接做
fmt.Printf(`
Usage: test
This program will start a daemon service, which you can use like this ...
`)
您全局定义 optQuit = make(chan struct{})
,然后在 main:optQuit := getopt.BoolLong("quit", 0, "Help")
中隐藏它。
所以主要的 optQuit 是 bool
,而不是 chan
删除 main 中的这两行:
optQuit := getopt.BoolLong("quit", 0, "Help")
optRun := getopt.BoolLong("run", 'r', "Help")