Отправка процесса в фоновый режим и возврат управления в мою оболочку
Я программирую оболочку для своего класса CS, и часть проекта включает в себя запуск процесса в фоновом режиме, если символ "&" передается пользователем.
Если процесс запускается на переднем плане, я просто execvp
процесс, и он остается под контролем терминала, так как он находится на переднем плане. Однако, если это фоновый процесс, я должен вернуть управление своей основной оболочке после начала выполнения процесса. Я понимаю, что системный вызов tcsetpgrp(pid_t)
помещает процесс в качестве аргумента на передний план, но я не совсем понимаю, как его использовать.
Я должен звонить tcsetpgrp
после execvp
если это фоновый процесс? Если да, могу ли я получить pid моей оболочки, просто позвонив getpid
?
3 ответа
tcsetpgrp()
работает над группами процессов, а не отдельными процессами. Что вы хотите сделать, это:
Когда вы создаете новый конвейер, звоните
setpgid()
поместить все элементы конвейера в новую группу процессов (с идентификатором PID первого процесса в конвейере в качестве PGID). (Конвейер - это последовательность процессов, запускаемых вашей оболочкой, когда она видит запрос вродеls | grep foo | wc -l
- самый простой конвейер имеет только один процесс). Обычно вы бы позвонилиsetpgid(0, 0)
от первого процесса в конвейере, до вызоваexec()
,использование
tcsetpgrp()
управлять тем, какая группа процессов находится на переднем плане. Если вы перемещаете группу процессов с переднего плана на фон, вы устанавливаете собственную группу процессов оболочки в качестве группы процессов переднего плана - вы можете получить это с помощьюgetpgid(0)
в оболочке.Когда оболочка находится в фоновом режиме, она должна использовать блокировку
waitpid()
вызов, чтобы дождаться завершения дочернего процесса, а не показывать подсказку. После завершения каждого процесса в конвейере переднего плана он должен снова вернуться на передний план (и показать подсказку).Когда оболочка находится на переднем плане, она должна вызвать
waitpid()
сWNOHANG
а такжеWUNTRACED
флажки для проверки состояния дочерних процессов непосредственно перед тем, как вы показываете приглашение - это сообщит вам, когда они остановились или вышли, и позволит вам проинформировать пользователя.
Вы должны взглянуть на fork, чтобы создать дочерний процесс. Затем используйте exec
в ребенке выполнить нужную команду.
Если ваша оболочка запускает процесс, используя &
чтобы справиться с этим, $!
Переменная shell будет содержать PID дочернего процесса. Вы можете отправить сигналы этому процессу или использовать wait $!
ждать его завершения.