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

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

问题描述

我想分叉进程并取回新进程的id,但是我可以在 exec os 库将启动一个新进程。 你应该想要 syscall.ForkExec()来自 syscall package。

请注意, fork()是在没有线程完全使用的情况下发明的,一个进程一直只有一个执行线程,因此分叉是安全的。随着Go的发展,这种情况完全不同,因为它大量使用操作系统级别的线程来支持其goroutine调度。



现在,没有经过培训的 fork(2) 将会使子进程只有单线程— fork(2)在父进程中 - 在所有活动的进程中,包括Go运行时使用的一些关键线程。基本上这意味着你只是简单地指望子进程不能继续执行Go代码,你唯一能做的事情就是立即执行 exec(2) 。请注意,这就是 syscall.ForkExec()用于。



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


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.

解决方案

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

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.

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 procss 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 suppsed to be used for.

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?

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

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