我如何 fork 一个 go 进程?

我想 fork 一个 go 进程并取回新进程的 id,但我在execoros库中看到的只是启动一个新进程。


犯罪嫌疑人X
浏览 313回答 3
3回答

BIG阳

你应该想syscall.ForkExec()从syscall包。请注意,fork()它是在根本不使用线程的时候发明的,并且一个进程中始终只有一个执行线程,因此分叉它是安全的。对于 Go,情况完全不同,因为它大量使用操作系统级线程来为其 goroutine 调度提供动力。现在,fork(2)在 Linux 上未经修饰将使子进程只有一个线程——fork(2)在父进程中调用的那个——在所有活动的线程中,包括 Go 运行时使用的一些关键线程。基本上这意味着您根本不能期望子进程能够继续执行 Go 代码,并且您唯一可以明智地做的就是以某种方式立即执行exec(2). 请注意,这syscall.ForkExec()就是应该用于的内容。现在进一步考虑这个问题。我想说现在直接调用唯一fork(2)有用的东西是“尽力而为的异步进程状态快照”——比如Redis使用的那种。这种技术依赖于子进程从其父进程继承所有内存数据页的事实,但操作系统使用写时复制技术并没有真正复制所有数据,因此子进程可以坐在那里保存所有数据结构到磁盘,而其父级正在自己的地址空间中修改它们。其他所有可以想到的 for 用法都fork()意味着直接exec(),这就是exec.Command()et al 的用途,那么为什么不使用它呢?

慕雪6442864

一种解决方案是exec.Command在其 goroutine 中使用执行。这就是这个小项目akshaydeo/go_process所做的:// Method to fork a process for given command// and return ProcessMonitorfunc Fork(processStateListener ProcessStateListener, cmdName string, cmdArgs ...string) {&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; processMonitor := &ProcessMonitor{}&nbsp; &nbsp; &nbsp; &nbsp; args := strings.Join(cmdArgs, ",")&nbsp; &nbsp; &nbsp; &nbsp; command := exec.Command(cmdName, args)&nbsp; &nbsp; &nbsp; &nbsp; output, err := command.Output()&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; processMonitor.Err = err&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; processStateListener.OnError(processMonitor, err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; processMonitor.Output = &output&nbsp; &nbsp; &nbsp; &nbsp; processStateListener.OnComplete(processMonitor)&nbsp; &nbsp; }()}该测试process_test.go显示了一些示例:// Test case for forkfunc TestFork(t *testing.T) {&nbsp; &nbsp; processStateListenerImpl := &ProcessStateListenerImpl{make(chan bool)}&nbsp; &nbsp; Fork(processStateListenerImpl,"ls", "-a") //("ping","192.168.3.141","-c","3")&nbsp; &nbsp; // waiting onto monitor&nbsp; &nbsp; <-processStateListenerImpl.monitor}

月关宝盒

分叉不仅仅用于并行处理。它还用于为无法关闭的关键服务提供冗余。如果您只有一个进程,则致命错误可能会导致整个事物、线程和所有事物消失。对于多进程应用程序,应用程序的另一个并行实例将继续处理,而“父”进程会产生一个新实例来替换崩溃的实例。Nginx、Apache 都以这种方式工作。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go