从非chan类型接收 *bool

Posted

技术标签:

【中文标题】从非chan类型接收 *bool【英文标题】:Receive from non-chan type *bool 【发布时间】:2017-11-22 15:50:52 【问题描述】:

我想守护 myapp,但我有一个大问题。我使用的频道类型为chan struct。 但是,使用包 getopt(标志包),我的标志是 *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

【问题讨论】:

这里似乎有点跑题了,不妨试试codereview.stackexchange.com 【参考方案1】:

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

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

【讨论】:

这是我想做的,我以为我必须使用getopt.BoolLong的返回才能在select函数中使用它...谢谢!【参考方案2】:

您在全局范围内定义 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")

【讨论】:

我了解您的解决方案,但我正在使用此软件包来获取帮助菜单...这是问题,我如何才能适应所有问题? 我不确定您要做什么。 optQuit 的打印帮助?然后只要有人给出参数h,就打印一个字符串。不要滥用软件包并杀死你的程序。

以上是关于从非chan类型接收 *bool的主要内容,如果未能解决你的问题,请参考以下文章

GoLang

GO (channel简单使用篇)

go语言学习笔记 — 进阶 — 并发编程:通道(channel) —— 各种各样的通道

从非类型模板参数确定类型

make(chan bool) 与 make(chan bool, 1) 的行为有何不同?

为啥 C# 无法从非泛型静态方法的签名推断泛型类型参数类型?