나는 프로세스를 포크하고 새로운 프로세스의 ID를 되찾고 싶지만, exec
또는 os
라이브러리에서 볼 수있는 것은 새로운 프로세스를 시작하는 것입니다.이동 프로세스를 어떻게 포크합니까?
답변
당신은 아마 syscall
패키지 syscall.ForkExec()
합니다.
fork()
은 스레드가 전혀 사용되지 않았을 때 만들어졌으며 프로세스는 항상 하나의 스레드 만 실행 했으므로 forking이 안전하다는 점에 유의하십시오. Go를 사용하면 상황에 따라 OS 레벨 스레드를 많이 사용하여 goroutine 일정을 강화할 수 있습니다.
이제 자식 프로세스를 만들 것입니다 리눅스에 꾸밈이 fork(2)
그냥 단일 스레드 — 이동 런타임에서 사용되는 몇 가지 중요한 스레드를 포함하여, 활성화 된 모든 중 부모 프로세스 —에 fork(2)
라는 사람이있다. 기본적으로이 말은 단순히 이 자식 코드 procss가 GO 코드 인을 계속 실행할 수 있다는 것을 기대할 수 없다는 것을 의미하며 사용자가 현명하게 수행 할 수있는 유일한 방법은 바로 exec(2)
을 수행하는 것입니다. 이것이 syscall.ForkExec()
에 사용되는 것으로 가정됩니다.
이제 문제에 대해 더 생각해보십시오. 지금은 fork(2)
에 대한 직접 호출이 "최선형 비동기 프로세스 상태 스냅 샷"인 경우 과 같은 종류의 —을 사용하는 것이 유일한 요즘이라고 말하고 싶습니다. 이 기법은 자식 프로세스가 부모로부터 모든 메모리 데이터 페이지를 상속 받지만 운영 체제는 모든 데이터를 실제로 복사하지 않기 위해 복사시 복사 기법을 사용하므로 자식이 거기 앉아서 모든 데이터 구조를 저장할 수 있습니다 부모가 자신의 주소 공간에서 수정하는 동안 디스크에 저장됩니다. fork()
에 대한 다른 모든 사용은 즉시 exec()
을 의미하며 그게 exec.Command()
외의 것이므로 사용하지 않는 이유는 무엇입니까?
하나의 해결 방법은 해당 goroutine에서 실행되는 exec.Command
을 사용하는 것입니다.
작은 프로젝트가 수행 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)
}()
}
The test 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
}
"fork()에 대한 다른 모든 사용은 즉각적인 exec()를 의미하며 exec.Command() 외의 것이므로 사용하지 않는 이유는 무엇입니까? setrlimit(), SELinux 설정, chroot() ing, 제어권을 양도하기 전에 FD를 닫거나 설정하는 것, 그리고 fork()와 exec() 사이에서 일어날 필요가있는 것입니까? –
"최선형 비동기 프로세스 상태 스냅 샷"이 * 정확하게 * 무엇을하려하는지? – cpcallen
@cpcallen, 나는 두렵다. "이런 식으로 진행하지 않을 것이다"* 이런 식으로. * 문제의 핵심은 Go 런타임이 OS 레벨 스레드에 대해 두 가지 일을한다는 것이다. a) goroutine ; b) 자신의 필요에 따라 사용합니다.단 하나의 쓰레드 만이 새로운 프로세스에서 다시 시작 되 자마자'fork()'에서 살아남 았기 때문에, 제대로 작동하는 것이 불가능한 절반의 상태가 될 것입니다. – kostix