如何开始一个过程?

daj*_*ood 10 go

我尝试从Google Go程序中启动JVM,如下所示:

package main
import "fmt"
import "os"
import "log"
func main() {

var name string
name="\\jrex64\\bin\\java.exe"

var path="-Xbootclasspath:jrex64\\lib\\rt.jar;"+
"jrex64\\lib\\jfxrt.jar;"+
"jrex64\\lib\\resources.jar;"+
"jrex64\\lib\\ext\\sunjce_provider.jar;"+
"jrex64\\lib\\ext\\zipfs.jar;"+
"jrex64\\lib\\ext\\sunmscapi.jar;"+
"jrex64\\lib\\ext\\sunec.jar;"+
"jrex64\\lib\\ext\\dnsns.jar;"+
"jrex64\\lib\\ext\\access-bridge-64.jar;"+
"jrex64\\lib\\security\\local_policy.jar;"+
"jrex64\\lib\\jce.jar;"+
"jrex64\\lib\\jfr.jar;"+
"jrex64\\lib\\jsse.jar;"+
"jrex64\\lib\\charsets.jar;"+
"jrex64\\lib\\";



var args[] string=make([]string,4)
args[0]="-verbose"
args[1]=path;
args[2]="-cp Ganesha_lib\\*"
args[3]="-jar Ganesha.jar"

var attr* os.ProcAttr

proc,err:=os.StartProcess(name,args,attr)
proc.Wait();


if err!=nil {
    fmt.Println("an error occurred.\n")
    log.Fatal(err)
}

}
Run Code Online (Sandbox Code Playgroud)

这是我的第一个Go程序.得到以下错误让我完全不知所措:

panic:运行时错误:无效的内存地址或nil指针取消引用[signal 0xc0000005 code = 0x0 addr = 0x0 pc = 0x4278b5] goroutine 1 [running]:os.startProcess(0x4aacb4,0x14,0xf840001eb0,0x500000005,0x0,...)C :/Users/ADMINI~1/AppData/Local/Temp/2/bindist767862039/go/src/pkg/os/exec_posix.go:28 + 0x152 os.StartProcess(0x4aacb4,0x14,0xf840001eb0,0x500000005,0x0,... )C:/Users/ADMINI~1/AppData/Local/Temp/2/bindist767862039/go/src/pkg/os/doc.go:24 + 0x5c main.main()D:/MyGoProject/src/main.go :60 + 0x23c goroutine 2 [syscall]:由runtime.main C创建:/Users/ADMINI~1/AppData/Local/Temp/2/bindist767862039/go/src/pkg/runtime/proc.c:221流程完成退出代码2

我如何解释此错误代码?什么地方出了错?我怎样才能获得JVM startet - 它位于Go可执行文件的子目录中.

Ste*_*erg 17

通常建议您不要直接使用os.StartProcess.相反,使用os/exec,它具有更简单的界面.这是我如何启动java子进程并等待它完成.

http://play.golang.org/p/APlp9KK9wx

package main

import (
    "fmt"
    "log"
    "os/exec"
    "strings"
)

func main() {
    var java = "\\jrex64\\bin\\java.exe"

    var path = []string{
        "jrex64\\lib\\rt.jar",
        "jrex64\\lib\\jfxrt.jar",
        "jrex64\\lib\\resources.jar",
        "jrex64\\lib\\ext\\sunjce_provider.jar",
        "jrex64\\lib\\ext\\zipfs.jar",
        "jrex64\\lib\\ext\\sunmscapi.jar",
        "jrex64\\lib\\ext\\sunec.jar",
        "jrex64\\lib\\ext\\dnsns.jar",
        "jrex64\\lib\\ext\\access-bridge-64.jar",
        "jrex64\\lib\\security\\local_policy.jar",
        "jrex64\\lib\\jce.jar",
        "jrex64\\lib\\jfr.jar",
        "jrex64\\lib\\jsse.jar",
        "jrex64\\lib\\charsets.jar",
        "jrex64\\lib\\",
    }

    pathflag := "-Xbootclasspath:" + strings.Join(path, ";")
    cmd := exec.Command(java, "-verbose", pathflag, "-cp Ganesha_lib\\*", "-jar Ganesha.jar")
    err := cmd.Run()

    if err != nil {
        fmt.Println("an error occurred.\n")
        log.Fatal(err)
    }

}
Run Code Online (Sandbox Code Playgroud)

如果你很好奇,你之所以感到恐慌的原因是attr是一个零指针.相反,你可以做到attr := new(os.ProcAttr).

  • 你需要所有那些 \\ 标记吗?因为 Windows 支持 Posix,我认为你可以使用 / 来代替,它更容易阅读并且可以移植到其他 Posix 文件系统(特别是 Linux、Macos) (2认同)

Dav*_*ill 7

以前的答案实际上并没有描述如何使用os.StartProcess().这是一个例子:

cmdToRun := "/path/to/someCommand"
args := []string{"someCommand", "arg1"}
procAttr := new(os.ProcAttr)
procAttr.Files = []*os.File{os.Stdin, os.Stdout, os.Stderr}
if process, err := os.StartProcess(cmdToRun, args, procAttr); err != nil {
    fmt.Printf("ERROR Unable to run %s: %s\n", cmdToRun, err.Error())
} else {
    fmt.Printf("%s running as pid %d\n", cmdToRun, process.Pid)
}
Run Code Online (Sandbox Code Playgroud)

请注意,有必要初始化ProcAttr.Files字段 - 如果不这样做,您可能会在os包中深入获得索引超出范围的错误.如果要在自己的代码中提供新进程的输入或进程输出,则可以使用管道作为文件.您可能还想指定Dir(起始目录)和Env(环境变量)字段.

  • 原因是直接使用os.StartProcess绝不是你想要做的事情.他没有问如何使用StartProcess,他问如何启动一个进程.我回答了为什么他的失败并指出他更好的实施方式.我不确定为什么他将你的答案标记为正确. (2认同)