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

У меня есть код C, который использует fork()+exec(), wait() (или waitpid()) и kill() и предполагает, что они существуют после включения соответствующих заголовков POSIX.

Теперь я хочу сделать этот код как можно более многоплатформенным — с минимальными изменениями. Таким образом, никаких зависимостей от сторонних библиотек и реализации этих средств в системах, в которых их нет. Однако для меня важно выйти за рамки только Linux, Windows и Mac OS. Мой инструмент для этого — CMake, который используется в проекте с этим кодом; и препроцессор Си. Может быть, немного клеевого кода на самом C.

Мой вопрос: что я должен проверить, что я должен поместить в сгенерированный включаемый файл и как мне изменить мой код, вызывающий эти функции, чтобы добиться одинакового поведения как на POSIX, так и на различных платформах, отличных от POSIX?

PS. Я понимаю, что на многих платформах нет сигналов в стиле Unix. Предположим для обсуждения, что я только завершаю процессы, а не посылаю другие сигналы.


person einpoklum    schedule 10.02.2019    source источник
comment
никаких зависимостей от сторонних библиотек и изобретения велосипедов -- мне кажется, что это два прямо противоречащих друг другу требования.   -  person Jonathon Reinhart    schedule 11.02.2019
comment
@JonathonReinhart: отредактировано, чтобы уточнить, что я имею в виду.   -  person einpoklum    schedule 11.02.2019
comment
Ну, тогда я не уверен, что вы ищете, кроме очевидного #ifdef HAVE_FORK решения.   -  person Jonathon Reinhart    schedule 11.02.2019
comment
Если вам нужен fork(), то выход за пределы Linux, Windows и Mac немного продвинется вперед, так как вам сначала придется обойти тот факт, что в Windows нет fork().   -  person John Bollinger    schedule 11.02.2019
comment
@JonathonReinhart: О, ну, именно это, за исключением того, что я хочу, если у вас есть fork + exec, используйте это; если у вас есть спавн, используйте его; если у вас есть что-то похожее, но с другим порядком параметров, используйте это и т. д. и т. д.   -  person einpoklum    schedule 11.02.2019
comment
Для меня важно выйти за рамки только Linux, Windows и Mac OS — Итак, куда вы планируете двигаться? Там не так много другого.   -  person    schedule 11.02.2019
comment
Основная проблема заключается в том, что в Windows нет прямого эквивалента функции fork (по крайней мере, когда я в последний раз использовал Win32 API), потому что ее модель процессов отличается от систем UNIX. Хотя есть эквиваленты waitpid и kill. Возможно, вы можете смоделировать функцию форка, создав тот же процесс с помощью CreateProcess, чем загрузить всю память первого процесса во второй процесс и переместить второй процесс в текущее местоположение первого процесса. Я не уверен, что последние шаги возможны/стабильны. Кроме того, включение Windows может изменить то, как вы управляете своими процессами в независимом от платформы API.   -  person unlut    schedule 11.02.2019
comment
@einpoklum Я до сих пор не уверен, что именно ты ищешь. Похоже, вы знаете, что процессы создания и завершения в разных операционных системах различаются, и поэтому вам придется писать код для каждой ОС. Я совершенно уверен, что вы не просто просите Stack Overflow написать это для вас, поэтому я пытаюсь выяснить, что именно вы ищете в ответе. Большая часть сложности, вероятно, заключается в особенностях #ifdef и/или в поведении системы сборки.   -  person Jonathon Reinhart    schedule 11.02.2019
comment
@JonathonReinhart: я как бы надеялся, что есть модули CMake, которые помогут вам с этим, и/или существующие проекты/библиотеки, которым нужно делать то же самое, из чего я мог бы извлечь несколько строк кода.   -  person einpoklum    schedule 11.02.2019


Ответы (1)


Окна

Ну, fork() (создать новый процесс) и exec() (запустить новую программу в этом процессе) не существует в Windows, просто и понятно. Вместо этого у вас есть CreateProcess, который сочетает в себе два.

Затем вы можете использовать TerminateProcess для , ну, завершить процесс.

Затем вы можете реализовать два отдельных файла .c: один для Windows и один для систем с fork()/exec().

POSIX

Если вас интересует только переносимость в средах POSIX (Linux, BSD, Mac OS), то posix_spawn() - определенно правильный путь. Он обрабатывает все тонкости обработки ошибок в дочернем процессе.

См. также: возможности `posix_spawn`

Кроссплатформенные библиотеки

Существует ряд кроссплатформенных фреймворков, которые решают эту проблему за вас:

Они, конечно, также решают ряд других проблем с переносимостью, поэтому лучше действительно «купиться» и использовать фреймворк для всего, что вы делаете, что взаимодействует с системой.

person Jonathon Reinhart    schedule 10.02.2019
comment
Это уже немного помогает мне, несмотря на то, что это не совсем то, что мне нужно. - person einpoklum; 11.02.2019