我如何 fork 一个 go 进程? [英] How do I fork a go process?

查看:44
本文介绍了我如何 fork 一个 go 进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想 fork 一个 go 进程并取回新进程的 id,但我在 execos 库中所能看到的就是开始一个新的进程.

I want to fork a go process and get back the id of the new process(es), but all I can see in the exec or os libraries is to start a new process.

推荐答案

你应该想要 syscall.ForkExec() 来自 系统调用 包.

You supposedly want syscall.ForkExec() from the syscall package.

请注意,fork() 是在根本没有使用线程的时候发明的,并且一个进程中始终只有一个执行线程,因此对它进行分叉是安全的.Go 的情况完全不同,因为它大量使用操作系统级线程来为其 goroutine 调度提供动力.

Note that fork() has been invented at the time when no threads were used at all, and a process had always had just a single thread of execution in it, and hence forking it was safe. With Go, the situation is radically different as it heavily uses OS-level threads to power its goroutine scheduling.

现在,Linux 上的 fork(2)将使子进程只有一个线程——在父进程中调用 fork(2) 的线程——在所有活跃的线程中,包括 Go 运行时使用的一些关键线程.基本上,这意味着您根本不能期望子进程能够继续执行 Go 代码,并且您唯一能明智地做的就是以某种方式立即执行 exec(2).请注意,这就是 syscall.ForkExec() 的用途.

Now, unadorned fork(2) on Linux will make the child process have just the single thread—the one which called fork(2) in the parent process—among all those which were active, including some crucial threads used by the Go runtime. Basically this means that you simply cannot expect the child process to be able to continue executing Go code, and the only thing you can sensibly do is to somehow immediately perform exec(2). Notice that that's what syscall.ForkExec() is supposed to be used for.

现在进一步考虑这个问题.我想说这些天直接调用 fork(2) 唯一有用的是尽力而为的异步进程状态快照"—那种,比如,Redis 使用.这种技术依赖于子进程从其父进程继承所有内存数据页的事实,但操作系统使用写时复制技术并没有真正复制所有数据,因此子进程可以坐在那里保存所有数据结构到磁盘,而其父级正在自己的地址空间中修改它们.fork() 的其他所有可能的用途都意味着立即使用 exec(),这就是 exec.Command() 等的用途,所以为什么只是不使用它?

And now think about the problem further. I'd say these days the only thing a direct call to fork(2) is useful for is "best-effort asynchronous process state snapshotting"—the kind, say, Redis uses. This technique relies on the fact the child process inherits all the memory data pages from its parent, but the OS uses copy-on-write technique to not really copy all that data, so the child can just sit there and save all the data structures to disk while its parent is chugging away modifying them in its own address space. Every other conceivable use for fork() implies immediate exec(), and that's what exec.Command() et al is for, so why just not use it?

这篇关于我如何 fork 一个 go 进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆