从非chan类型* bool接收

时间:2017-06-20 08:07:26

标签: pointers go struct daemon channel

我想守护myapp,但我有一个大问题。我使用的频道属于chan struct{}类型。 但是,使用包getopt(flag包),我的标志是* bool类型,所以我不知道如何修改myapp。

渠道类型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,该应用程序会正常关闭。你可以在你的机器上运行它:

https://play.golang.org/p/RVq7M7usEj

2 个答案:

答案 0 :(得分:0)

主函数中的这两行会影响全局变量声明:

optQuit := getopt.BoolLong("quit", 0, "Help")
optRun  := getopt.BoolLong("run", 'r', "Help")

如果您只使用它们,为了获得良好的用法,为什么不创建一个使用功能 自己?

如果您坚持仅使用getopt来创建用法,请执行

_ = getopt.BoolLong("quit", 0, "Help")
_ = getopt.BoolLong("run", 'r', "Help")

代替。

您还需要在使用getopt.Parse()之前致电*optHelp

结果消息

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 ...
`)

答案 1 :(得分:0)

您全局定义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")