为了账号安全,请及时绑定邮箱和手机立即绑定

我如何 fork 一个 go 进程?

我如何 fork 一个 go 进程?

Go
犯罪嫌疑人X 2021-09-13 15:41:00
我想 fork 一个 go 进程并取回新进程的 id,但我在execoros库中看到的只是启动一个新进程。
查看完整描述

3 回答

?
BIG阳

TA贡献1859条经验 获得超6个赞

你应该想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 的用途,那么为什么不使用它呢?


查看完整回答
反对 回复 2021-09-13
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

一种解决方案是exec.Command在其 goroutine 中使用执行。


这就是这个小项目akshaydeo/go_process所做的:


// Method to fork a process for given command

// and return ProcessMonitor

func Fork(processStateListener ProcessStateListener, cmdName string, cmdArgs ...string) {

    go func() {

        processMonitor := &ProcessMonitor{}

        args := strings.Join(cmdArgs, ",")

        command := exec.Command(cmdName, args)

        output, err := command.Output()

        if err != nil {

            processMonitor.Err = err

            processStateListener.OnError(processMonitor, err)

        }       

        processMonitor.Output = &output

        processStateListener.OnComplete(processMonitor)

    }()

}

该测试process_test.go显示了一些示例:


// Test case for fork

func TestFork(t *testing.T) {

    processStateListenerImpl := &ProcessStateListenerImpl{make(chan bool)}

    Fork(processStateListenerImpl,"ls", "-a") //("ping","192.168.3.141","-c","3")

    // waiting onto monitor

    <-processStateListenerImpl.monitor

}


查看完整回答
反对 回复 2021-09-13
?
月关宝盒

TA贡献1772条经验 获得超5个赞

分叉不仅仅用于并行处理。它还用于为无法关闭的关键服务提供冗余。如果您只有一个进程,则致命错误可能会导致整个事物、线程和所有事物消失。

对于多进程应用程序,应用程序的另一个并行实例将继续处理,而“父”进程会产生一个新实例来替换崩溃的实例。

Nginx、Apache 都以这种方式工作。


查看完整回答
反对 回复 2021-09-13
  • 3 回答
  • 0 关注
  • 310 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号