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

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

19.08.2008 22:53:47
Я думаю, что вам нужно переписать свой вопрос - открытие внешнего процесса не совсем то же самое, что порождение другого процесса ... есть разница.
Jason Bunting 19.08.2008 23:01:03
8 ОТВЕТОВ
#include <stdlib.h>

int main()
{
    system("echo HAI");

    return 0;
}
11
16.04.2015 23:13:35
Никогда не используйте систему. Это не безопасно для многопоточности, так как это сильно укусит вас там, где это действительно больно. Например, ошибки обработки сигналов являются одними из самых неприятных проблем, и «система» полна ими.
Lothar 28.12.2012 18:29:08

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

int system(const char *string);

Пример системного API

2
19.08.2008 22:59:56

В 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);

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

3
12.09.2016 11:04:26

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

#include <stdio.h>

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
...
16
20.08.2008 01:52:59
if (!feof(output)) return -1; pclose(output); return 0;(Нет, pclose(output)если !feof(output)по примеру от Microsoft .)
7vujy0f0hy 30.12.2018 09:29:51

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

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

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

#include <unistd.h>
#include <stdio.h>

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 ребенка
LOL родителя

Если у вас fork()pid, возвращенный в потомке, равен 0, а pid, возвращенный в родительском, - это pid ребенка. Обратите внимание, что "hi2u" печатается только один раз ... родителем .

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

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

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

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

19
21.08.2008 18:44:38

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

1
23.12.2008 16:08:56

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

1
23.12.2008 16:30:10

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

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

7
28.12.2012 18:33:44