Я хочу развить процесс и вернуть идентификатор нового процесса (ов), но все, что я вижу в библиотеках exec
или os
, - это начать новый процесс.Как мне преобразовать процесс?
ответ
Вы хотите, мол, syscall.ForkExec()
из syscall
пакета.
Отметьте, что fork()
был изобретен в то время, когда нити не использовались вообще, и процесс всегда имел только один поток выполнения в нем, и, следовательно, разветвление было безопасным. С Go ситуация кардинально отличается, так как она сильно использует потоки уровня ОС для управления графиком goroutine.
Теперь прикрасы fork(2)
на Linux сделает процесс ребенка есть только один поток — тот, который называется fork(2)
в родительском процессе — среди всех тех, которые были активны, в том числе некоторых важных потоков, используемых во время выполнения Go. В основном это означает, что вы просто не можете ожидать, что дочерний procss сможет продолжить выполнение кода Go,, и единственное, что вы можете разумно сделать, это как-то сразу выполнить exec(2)
. Обратите внимание, что для этого используется syscall.ForkExec()
.
А теперь подумайте о проблеме дальше. Я бы сказал, что в эти дни единственное, что прямой вызов fork(2)
полезен для «моментального снимка состояния асинхронного процесса» с максимальным усилием, — вид, скажем, Redis. Этот метод основан на том, что дочерний процесс наследует все страницы данных памяти от его родителя, но ОС использует метод копирования на запись, чтобы не копировать все эти данные, поэтому ребенок может просто сидеть там и сохранять все структуры данных на диск, в то время как его родительский язык отключается, изменяя их в своем адресном пространстве. Каждое другое возможное использование для fork()
подразумевает немедленный exec()
, и вот что такое exec.Command()
и др., Так почему бы просто не использовать его?
Одним из решений является использование 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)
}()
}
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
}
Это forking 'ls' процесс. Я хочу разблокировать тот же процесс, который я запускаю. Как я могу это сделать - 'fork'' C++ '? – Shashwat
@Shashwat не уверен: я видел только обратное (http://stackoverflow.com/q/22805059/6309) – VonC
Я угадываю здесь: в блоке 'if err! = Nil' отсутствует' return' «Форк». –
- 1. Хотите преобразовать процесс в многопоточный процесс
- 2. Как мне выполнить текущий процесс?
- 3. Как мне преобразовать Enum?
- 4. Как мне преобразовать приложение WinForms?
- 5. Как мне преобразовать регулярное выражение?
- 6. Как мне преобразовать протокол приложения?
- 7. Как мне получить процесс перезагрузки в linux?
- 8. Как мне улучшить процесс развертывания приложения perl?
- 9. Как мне «приятно» уже запущен процесс?
- 10. Как мне сделать процесс на C++?
- 11. Как мне преобразовать известное значение циклической избыточности?
- 12. Асинхронного процесс дает мне неприятность
- 13. Как мне преобразовать это JSON datetime?
- 14. Как мне преобразовать HTML-вход в form_for?
- 15. Как мне преобразовать текущее время в GMT?
- 16. Как мне преобразовать из NSString в NSDate?
- 17. Как мне преобразовать этот 1471323637 вовремя
- 18. jQuery: как мне преобразовать это в 1.3.2?
- 19. Как мне преобразовать из std :: wstring _TCHAR []?
- 20. Как мне преобразовать математическое уравнение в php?
- 21. Как мне преобразовать это значение MongoDB Date?
- 22. Как мне преобразовать это в EJS?
- 23. Как мне преобразовать дату в PHP?
- 24. Как мне преобразовать буквы в числа?
- 25. Как мне преобразовать это в lambda
- 26. мне нужно преобразовать массив JSON
- 27. Мне нужно было преобразовать координаты?
- 28. Почему дочерний процесс завершен ?? пожалуйста, объясните мне?
- 29. Помогите мне автоматизировать процесс подачи магазина приложения
- 30. Когда мне нужно закрыть процесс NodeJS?
«Любое другое возможное использование fork() подразумевает немедленный exec(), и это то, что exec.Command() и др., Так почему бы просто не использовать его?» Есть setrlimit(), настройка SELinux, chroot() ing, закрытие или настройка FDs перед передачей управления - и это должно произойти между fork() и exec(), no? –
Что делать, если «мгновенный снимок состояния асинхронного процесса с наилучшим усилием» - это именно то, что я пытаюсь сделать? – cpcallen
@cpcallen, боюсь, это будет «не в Go» * таким образом. Суть проблемы в том, что среда выполнения Go делает две вещи для потоков уровня ОС: a) использует их для питания ваших goroutines ; б) использует их для своих нужд.Так как только один поток выживает 'fork()', как только он будет возобновлен в новом процессе, он будет находиться в полуобеспеченном состоянии, что невозможно работать должным образом. – kostix