Question:
如何分叉一个 Go 进程并获取新进程的 ID?
Answer:
要分叉一个 Go 进程并获取新进程的 ID,可以使用 syscall.ForkExec() 函数,该函数位于 syscall 包中。
需要注意的是,Go 库中的 fork() 函数无法满足您的需求。
最初发明 fork() 函数时,并没有使用线程,而且进程始终只有一个执行线程,因此分叉是安全的。然而,Go 大量使用操作系统级的线程来驱动 goroutine 调度,这使得情况发生了根本性的变化。
现在,Linux 上未修饰的 fork(2) 仅使子进程拥有在父进程中调用 fork(2) 的单个线程,而 Go 运行时使用的所有线程(包括一些关键线程)都不在其中。基本上这意味着您 不能指望子进程能够继续执行 Go 代码,您唯一可以合理做的事情就是立即执行 exec(2)。请注意,这就是 syscall.ForkExec() 应该用于的目的。
现在进一步思考一下这个问题。我认为现在直接调用 fork(2) 唯一有用的事情是“尽力异步进程状态快照”,例如 Redis 使用的那种。这种技术依赖于这样一个事实:子进程继承其父进程的所有内存数据页,但是操作系统使用写时复制技术而不真正复制所有数据,因此子进程可以停在那里并将所有数据结构保存到磁盘,而它的父进程正在修改它自己的地址空间中的数据。而 fork() 的任何其他可能的用途都意味着即时 exec(),而这正是 exec.Command() 等函数的用途,那么为什么要使用 fork() 呢?
以上是如何分叉 Go 进程并检索其 PID?的详细内容。更多信息请关注PHP中文网其他相关文章!