Передать указатель на целое число при вызове execv в C
Я пишу рудиментарную программу оболочки на C, которая использует родительский процесс для обработки событий оболочки и fork() для создания дочерних процессов, которые вызывают execv для другого исполняемого файла (также C).
Я пытаюсь сохранить счетчик процесса на родительском процессе. И поэтому я подумал о возможности создания указателя на переменную, которая отслеживает, сколько процессов запущено.
Однако это кажется невозможным, так как аргументы execv (и выполняемая им программа) имеют тип char * const argv[]
,
Я пытался отслеживать количество процессов, использующих mmap для совместной памяти между процессами, но не смог заставить это работать, так как после вызова execv процесс просто умирает и не позволяет мне обновить счетчик процесса.
Итак, мой вопрос: есть ли способ передать указатель на целое число при вызове execv другой программы?
Заранее спасибо.
1 ответ
Вы не можете осмысленно передать указатель от одного процесса другому, потому что указатель не имеет смысла в другом процессе. Каждый процесс имеет свою собственную память, и адрес относительно этого пространства памяти. Другими словами, менеджер виртуальной памяти позволяет каждому процессу притворяться, что он имеет всю память машины; другие процессы просто невидимы.
Однако у вас есть несколько вариантов настройки связи между связанными процессами. Наиболее очевидным является труба, с которой вы, вероятно, уже сталкивались. Это больше работы, потому что вам нужно убедиться, что какой-то процесс всегда прослушивает канал связи.
Другая простая возможность - просто оставить файловый дескриптор открытым, когда вы выполняете fork и exec (смотрите флаг close-on-exec, чтобы узнать, как этого добиться); хотя mmap
не сохраняется exec
Вы можете переназначить память на открытый файл в дочернем процессе. Если вы не хотите передавать fd, вы можете отобразить память во временный файл и использовать переменную среды для записи имени временного файла.
Другая возможность - общая память Posix. Опять же, вы можете сообщить имя shm через переменную окружения, а не жестко кодировать его в приложении.
Обратите внимание, что ни общие карты, ни общая память не являются атомарными. Если вы увеличиваете счетчик, вам нужно использовать механизм блокировки, чтобы избежать условий гонки.
Возможно, для получения гораздо большей информации, чем вы действительно хотели, вы можете прочитать обзор ESR о методах межпроцессного взаимодействия в главе 7 "Искусство программирования Unix".