Получение фактического идентификатора процесса команды, которая выполняется в фоновом режиме с использованием C ++

0

Допустим, я выполнил простой фоновый процесс, который:

sleep 25 &

Я выполняю его в командной строке как:

> sleep 25 &
[1] 26390
> ps
   PID TTY         TIME CMD
 26390 pts/52      0:00 sleep
  6746 pts/52      0:02 tcsh
 26391 pts/52      0:00 ps
> 

Вы можете видеть, что сон выполняется в фоновом режиме с помощью pid 26390 Теперь я пытаюсь сделать то же самое, используя c++. Есть много разных системных вызовов, чтобы сделать это кстати.

using system
using fork
using pipe

Я попробовал под кодом:

if(p=fork()){
//Main process
cout<<p<<endl;
}
else{
execv("sleep 20 &",(char **)NULL);
}
}

выход:

> ./a.out
27391
> ps
   PID TTY         TIME CMD
  6746 pts/52      0:02 tcsh
 27392 pts/52      0:00 ps
> 

Вы можете видеть, что в фоновом режиме нет сна. Теперь я попробовал другой способ:

FILE* pipe = popen("sleep 20 &", "r");
    if(pipe){
                char buffer[128];
                while(fgets(buffer, 128, pipe));
                cout<<buffer<<endl;
                pclose(pipe);
             }

Это зависает в течение 20 секунд, и я никогда не получу этот файл cout с идентификатором процесса.

> ./a.out

> 

Опять я попробовал другой способ:

if(p=fork()){
//Main process
cout<<p<<endl;
}
else{
system("sleep 20 &");
}
}

> ./a.out
27464
> ps
   PID TTY         TIME CMD
 27466 pts/52      0:00 sleep
 27467 pts/52      0:00 ps
  6746 pts/52      0:02 tcsh

Теперь вы можете видеть, что сон работает в фоновом режиме, но с другим PID.

Но мне нужен фактический pid команды sleep, который выполняется в фоновом режиме. Я твердо верю, что должен быть какой-то способ получить точный pid процесса, выполняющегося в фоновом режиме в c++. Может ли кто-нибудь помочь?

Теги:
process
solaris

4 ответа

3
Лучший ответ

Идентификатор процесса, который вы распечатываете, является правильным. Проблема в том, что ваш сон не начинается правильно.

Нет необходимости иметь "&" в аргументах для сна; ваш код уже делает это. Если у вас есть "&", сон скорее всего будет жаловаться, потому что "&" не является продолжительностью.

Вместо этого попробуйте выполнить вызов exec:

execlp("sleep", "sleep", "20", 0);

Это ищет каталоги в PATH для файла, называемого "sleep", и заменяет текущий процесс этим процессом, вызванным спящими аргументами и "20". Эти аргументы передаются main() с использованием argv и argc.

Прочтите справочную страницу для exec для получения более подробной информации.

  • 0
    Большое спасибо, Янм. Это сработало.
1

Как указывали другие, PID, который вы указали для команды sleep, является PID самой команды сна (то есть, что вы сказали, что вам нужно). Таким образом, PID, который вы распечатали из процесса, - 27464, а PID сона, который вы создали с помощью системы(), - 27466. Возможно, если вы скажете больше о том, что вы пытаетесь сделать, мы сможем помочь.

1

Семейство функций exec не принимает команды оболочки, и они не запускают оболочки. Вместо этого они заменяют процесс одним загруженным с диска. То, как вы используете функцию execv не получится.

С другой стороны, system функция фактически запускает оболочку для выполнения команд (ов).

Способ получить pid процесса очень прост: используйте функцию getpid. Как в

std::cout << "pid = " << getpid() << '\n';

Если вы используете fork и используете выше, прежде чем надлежащий вызов функции exec отобразит pid процесса, который будет спать. Но нет, если вы вызываете system или popen, потому что эти функции сами fork новые процессы. Говоря о system, если вы поместите ее в свой собственный процесс, вам не нужно использовать & для запуска в фоновом режиме, сам дочерний процесс гарантирует, что команда уже находится в фоновом режиме.

  • 0
    используя getpid для exec !!! .. Подскажите, пожалуйста, как?
  • 0
    @Vijay Позвони в getpid как я показал в своем ответе. Тогда вызовите exec .
Показать ещё 1 комментарий
1

Считайте оболочку C считающейся вредной, затем переключитесь на приятную интерактивную оболочку (например, zsh, fish, bash). Для сценариев рассмотрите Posix sh (или используйте реальные языки сценариев).

Прочтите расширенное программирование на Linux (большая часть его ценна для других систем Unix, включая Solaris).

Вы должны научиться использовать fork (2), getpid (2), execve (2), pipe (2), waitpid (2) и т.д. (Они стандартизованы POSIX). Мы не можем тратить часы, чтобы научить вас этому, но вы определенно должны читать книги о них. Понимание того, как работает вилка, сложно.

Возможно, вам понадобится вызвать функцию sleep (3) или нейлоновый (2) syscall. Вы не должны использовать system или popen для sleep (оба будут разрывать процесс оболочки, который в этом случае бесполезен), просто вызовите функцию!

Не забывайте, что stdio (3) буферизуется. Вероятно, вам нужно вызвать fflush (3) (в C) или std::flush в C++, мудро (в частности, перед fork).

  • 0
    @Basile .. Спасибо за ваши предложения. Но я чувствую, что это не тот ответ, который я ожидаю. Я не хочу, чтобы ты научил меня всему здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню