Читать книгу 📗 "QNX/UNIX: Анатомия параллелизма - Цилюрик Олег Иванович"
Создание нового процесса
Созданию процессов (имеется в виду создание процесса из программного кода) посвящено столько описаний [1-9], что детальное рассмотрение этого вопроса было бы лишь пересказом. Поэтому мы ограничимся только беглым перечислением этих возможностей, тем более что в ходе обсуждения нас главным образом интересуют не сами процессы, а потоки, заключенные в адресных пространствах процессов.
Использование командного интерпретатора
Самый простой способ — запустить из программного кода дочернюю копию командного интерпретатора, которому затем передать команду запуска процесса. Для этого используется вызов:
int system(const char* command);где
commandФункция имеет еще одну специфическую форму вызова, когда в качестве
commandNULLНа время выполнения вызова
system()system()WEXITSTATUS()<sys/wait.h>
#include <sys/wait.h>
int main(void) {
int rc = system("ls");
if (rc == -1) cout << "shell could not be run" << endl;
else
cout << "result of running command is " << WEXITSTATUS(rc) << endl;
return EXIT_SUCCESS;
}Эта функция использует вызов
spawnlp()spawnlp()/bin/shВызов
system()• Используя копию командного интерпретатора, вызов
system()• Остановка родительского процесса в ожидании завершения порожденного также легко разрешается: просто запускайте дочерний процесс из отдельного потока [11]:
#include <pthread.h>
void* process(void* command) {
system((char*)command);
delete command;
return NULL;
}
int main(int argc, char *argv[]) {
...
char* comstr = "ls -l";
pthread_create(NULL, NULL, strdup(comstr), &process);
...
}• Часто в качестве недостатка этого способа отмечают «автономность» и невозможность взаимодействия родительского и порожденного процессов.
Но для расширения возможностей взаимосвязи процессов можно прежде всего воспользоваться вызовом
popen()system()popen()
FILE* popen(const char* command, const char* mode);где
commandsystem()modemodemodemodeВ результате выполнения этой функции создается открытый файловый дескриптор канала (pipe), из которого породивший процесс может (
modeSTDOUT_FILENOmodeSTDIN_FILENOРассмотрим следующий пример. Конечно, посимвольный ввод/вывод — это не лучшее решение, и здесь мы используем его только для простоты:
int main(int argc, char** argv) {
FILE* f = popen("ls -l", "r");
if (f == NULL) perror("popen"), exit(EXIT_FAILURE);
char c;
while((с = fgetc(f)) != EOF )