Как вы создаете другой процесс в C?

Как запустить внешнюю программу и передать ее параметры командной строки с помощью C? Если вам нужно использовать API операционной системы, включите решение для Windows, Mac и Linux.

Это действительно зависит от того, что вы пытаетесь сделать, точно так же, как это:

  1. Зависит от ОС
  2. Не совсем понятно, что вы пытаетесь сделать.

Тем не менее, я постараюсь предоставить вам некоторую информацию.
В UNIX fork() создает клон вашего процесса с того места, где вы вызывали fork. Если у меня есть следующий процесс:

 #include  #include  int main() { printf( "hi 2 u\n" ); int mypid = fork(); if( 0 == mypid ) printf( "lol child\n" ); else printf( "lol parent\n" ); return( 0 ); } 

Результат будет выглядеть следующим образом:

привет 2 u
lol child
lol parent

Когда вы fork() pid, возвращаемый в дочернем элементе, равен 0, а pid, возвращаемый в родительском элементе, является pid ребенка. Обратите внимание, что «hi2u» печатается только один раз … родителем .

execve() и его семейство функций почти всегда используются с fork(). execve() и т.п. переписывают текущую стек-фрейму с именем приложения, которое вы передаете ему. execve() почти всегда используется с fork() где вы разыгрываете дочерний процесс, и если вы являетесь родителем, вы делаете все, что вам нужно, и если вы ребенок, вы выполняете новый процесс. execve() также почти всегда используется с waitpid() – waitpid принимает pid дочернего процесса и, буквально, ждет, пока ребенок не завершит работу и не вернет вам статус выхода ребенка.

Используя эту информацию, вы должны иметь возможность написать очень базовую оболочку; который принимает имена процессов в командной строке и запускает процессы, о которых вы говорите. Разумеется, оболочки делают больше, чем такие, как ввод и вывод труб, но вы должны быть в состоянии выполнить основы, используя fork() , execve() и waitpid() .

ПРИМЕЧАНИЕ. Это спецификация * nix! Это НЕ будет работать в Windows.

Надеюсь, это помогло.

Если вы хотите выполнять более сложные операции, такие как чтение выходных данных внешней программы, вам может быть лучше обслуживать системный вызов popen . Например, для программного доступа к списку каталогов (это несколько глупый пример, но полезный в качестве примера), вы могли бы написать что-то вроде этого:

 #include  int main() { int entry = 1; char line[200]; FILE* output = popen("/usr/bin/ls -1 /usr/man", "r"); while ( fgets(line, 199, output) ) { printf("%5d: %s", entry++, line); } } 

для вывода такой информации

 1: cat1 2: cat1b 3: cat1c 4: cat1f 5: cat1m 6: cat1s ... 
 #include  int main() { system("echo HAI"); return 0; } 

Я хочу дать большое предупреждение не использовать систему, а 100% никогда не использовать систему при написании библиотеки. Он был разработан 30 лет назад, когда multithreading была неизвестна операционной системе игрушек под названием Unix. И он по-прежнему не используется, даже когда почти все программы сегодня многопоточны.

Используйте popen или создайте fork + execvp, все остальное вам будет сложно найти проблемы с обработкой сигналов, сбоями в коде обработки среды и т. Д. Это чистое зло и позор, что выбранный и самый рейтинговый ответ способствует использованию «системы ». Более здорово продвигать использование Cocain на рабочем месте.

В UNIX, я думаю, вам в основном нужно разветвить его, если вы хотите, чтобы порожденный процесс работал отдельно от вашего раскалывающего: например, если вы не хотите, чтобы ваш порожденный процесс завершился, когда вы покинули процесс нереста.

Вот страница, в которой объясняются все тонкие различия между Fork, System, Exec.

Если вы работаете в Win, Mac и Linux, я могу порекомендовать вам Qt Framework и объект QProcess , но я не знаю, подходит ли это вам. Большие преимущества заключаются в том, что вы сможете скомпилировать один и тот же код в windows linux и mac:

  QString program = "./yourspawnedprogram"; QProcess * spawnedProcess = new QProcess(parent); spawnedProcess->start(program); // or spawnedProcess->startDetached(program); 

Кроме того, вы можете даже убить дочерний процесс из материнского процесса и поддерживать связь с ним через stream.

Одним из решений является системная функция, определенная в stdlib.h

 int system(const char *string); 

пример системы api

Если вам нужно проверить / прочитать / проанализировать вывод своей внешней команды, я бы предложил использовать popen () вместо system ().

Говоря о зависимых от платформы рецептах, в Windows используйте CreateProcess , на Posix (Linux, Mac) используйте fork + execvp . Но system() должен покрывать ваши основные потребности и является частью стандартной библиотеки.