Переходит ли exe c непосредственно к новому процессу, который он создает? Или по прерыванию ядра? - PullRequest
1 голос
/ 02 августа 2020

В UNIX новый процесс запускается системным вызовом exec. Что касается запуска нового процесса, в книге Принципы и практика операционных систем говорится, что сначала ОС выделяет новую память для нового процесса, затем сохраняет начальные состояния в стек прерываний ядра и, наконец, запускает процесс путем выхода из ядра с помощью инструкций popad и iret, которые устанавливают состояния процессора в состояния, хранящиеся в стеке прерываний ядра, и переходит на кодовый адрес, хранящийся в стеке прерываний ядра.

Но мне интересно , почему бы просто не установить начальные состояния и не перейти к новому процессу непосредственно в функции exec?

И есть ли что-нибудь неправильное в моем утверждении относительно того, как процесс запускается прерыванием ядра?

Ответы [ 2 ]

1 голос
/ 02 августа 2020

В UNIX новый процесс запускается системным вызовом exec.

Не совсем. fork или clone создают новый процесс. exec заменит текущую запущенную программу другой программой внутри существующего процесса.

Но мне интересно, почему бы просто не установить начальные состояния и не перейти к новому процессу прямо в exe c function?

Это будет означать, что вы хотите полностью эмулировать exec() на уровне пользователя (используя open(), read() et c.) вместо использования ядра .

Во многих случаях это теоретически возможно. Однако в некоторых случаях это невозможно. (Подумайте о файле с -rws--x--x правами доступа!)

И для этого потребуется, чтобы весь интерпретатор формата файла был в функции exec() на уровне пользователя. Особенно при использовании статически связанных исполняемых файлов каждая программа, вызывающая exec(), должна содержать код, который анализирует формат исполняемых файлов.

В этом случае разные программы могут поддерживать разные форматы файлов: Некоторые программы, написанные для Linux ядер 1.2.13 сможет запускать оба (недавно представленные) ELF и a.out исполняемые файлы, в то время как другие смогут запускать только a.out файлы; не все программы могут быть запущены всеми программами.

Реализация ядра (с использованием системного вызова) будет поддерживать или не поддерживать определенный тип файла независимо от программы, которая вызывает exec().

Следующая проблема состоит в том, что реализация на уровне пользователя может «забыть» некоторый код деинициализации: допустим, вы используете реализацию exec(), написанную для Linux 2.4, и вызываете системный вызов timer_create(). Поскольку реализация exec() не знает о существовании таких таймеров, она не остановит таймер.

Реализация ядра (с использованием системного вызова) знает все функции операционной системы и, следовательно, очищает "старые" программа »полностью перед запуском новой.

1 голос
/ 02 августа 2020

Exe c не создает NOT новый процесс. Fork делает.

Семейство функций exe c () заменяет текущий образ процесса с новым образом процесса.

Проверка glib c реализации _execve

/* Replace the current process, executing FILE_NAME with arguments ARGV and
   environment ENVP.  ARGV and ENVP are terminated by NULL pointers.  */

Вы можете погрузиться в подробности и посмотреть, как это реализовано.

Но мне интересно, почему бы просто не установить начальные состояния и не перейти к новому процессу непосредственно в функции exe c?

Так работают потоки, процесс имеет собственное состояние , с собственным приоритетом, файловыми дескрипторами, таблицей прерываний и т. д.

...