Чтение онлайн

на главную

Жанры

QNX/UNIX: Анатомия параллелизма
Шрифт:

• RID и EUID — реальный и эффективный идентификаторы пользователя. Эффективный идентификатор служит для определения прав доступа процесса к системным ресурсам (в первую очередь к файловым системам). Обычно RID и EUID совпадают, но установка флага SUID для исполняемого файла процесса позволяет расширить полномочия процесса.

• RGID и EGID — реальный и эффективный идентификаторы группы пользователей. Как и в случае идентификаторов пользователя, EGID не совпадает с RGID, если установлен флаг SGID для исполняемого файла процесса.

Часто в качестве атрибутов процесса называют и приоритет выполнения. Однако приоритет является атрибутом не процесса (процесс — это статическая субстанция, контейнер), а потока, но если поток единственный (главный, порожденный функцией

main
), его приоритет
и есть то, что понимается под «приоритетом процесса».

Создание нового процесса

Созданию процессов (имеется в виду создание процесса из программного кода) посвящено столько описаний [1-9], что детальное рассмотрение этого вопроса было бы лишь пересказом. Поэтому мы ограничимся только беглым перечислением этих возможностей, тем более что в ходе обсуждения нас главным образом интересуют не сами процессы, а потоки, заключенные в адресных пространствах процессов.

Использование командного интерпретатора

Самый простой способ — запустить из программного кода дочернюю копию командного интерпретатора, которому затем передать команду запуска процесса. Для этого используется вызов:

int system(const char* command);

где

command
— текстовая строка, содержащая команду, которую предполагается выполнить ровно в том виде, в котором мы вводим ее командному интерпретатору с консоли.

Примечание

Функция имеет еще одну специфическую форму вызова, когда в качестве

command
задается
NULL
. По коду возврата это позволяет выяснить, присутствует ли (и доступен ли) командный интерпретатор в системе (возвращается 0, если интерпретатор доступен).

На время выполнения вызова

system
вызывающий процесс приостанавливается. После завершения порожденного процесса функция возвращает код завершения вновь созданной копии интерпретатора (или -1, если сам интерпретатор не может быть выполнен), то есть младшие 8 бит возвращаемого значения содержат код завершения выполняемого процесса. Возврат вызова
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
для загрузки новой копии командного интерпретатора, то есть «внутреннее устройство» должно быть в общем виде вам понятно. Особенностью QNX-реализации является то, что
spawnlp
всегда использует вызов
/bin/sh
, независимо от конкретного вида интерпретатора, устанавливаемого переменной окружения SHELL (ksh, bash…). Это обеспечивает независимость поведения родительского приложения от конкретных установок системы, в которой это приложение выполняется.

Вызов

system
является не только простым, но и очень наглядным, делающим код легко читаемым. Программисты часто относятся к нему с пренебрежением [10] , отмечая множество его недостатков. Однако в относительно простых случаях это может быть оптимальным решением, а недостатки не так и существенны:

• Используя копию командного интерпретатора, вызов

system
может инициировать процесс, исполняющий и бинарную программу, и скрипт на языке самого командного интерпретатора (shell), а также программный код на интерпретирующих языках, таких как Perl, Tcl/Tk и др. Многие из рассматриваемых ниже «чисто программных» способов могут загружать и исполнять только бинарный исполняемый код (по крайней мере, без использования ими весьма громоздких искусственных и альтернативных возможностей).

10

Здесь многое зависит от расстановки приоритетов. Если вы хотите, чтобы всякий, читающий ваш код, тут же воскликнул: «Ну и крутой же парень написал такое!», заведомо используйте

spawn
. При желании сделать код максимально элегантным используйте
fork
, а если ставится задача хорошей читаемости и ясности кода, то очень часто достаточно и
system
.

• Остановка родительского процесса в ожидании завершения порожденного также легко разрешается: просто запускайте дочерний процесс из отдельного потока [11] :

#include <pthread.h>

void* process(void* command) {

system((char*)command);

delete command;

return NULL;

}

int main(int argc, char *argv[]) {

11

Детали создания потока и и частности передачи ему параметра обстоятельно рассматриваются далее.

...

char* comstr = "ls -l";

pthread_create(NULL, NULL, strdup(comstr), &process);

...

}

• Часто в качестве недостатка этого способа отмечают «автономность» и невозможность взаимодействия родительского и порожденного процессов.

Но для расширения возможностей взаимосвязи процессов можно прежде всего воспользоваться вызовом

popen
(POSIX 1003.1a), являющимся в некотором роде эквивалентом, расширяющим возможности
system
. Возможности
popen
часто упускаются из виду, так как в описаниях этот вызов относится не к области создания процессов, а к области программных каналов (pipe). Синтаксис этого вызова таков:

FILE* popen(const char* command, const char* mode);

где

command
командная строка, как и у
system
;
mode
— режим создаваемого программного канала со стороны порождающего процесса: ввод (
mode
= «r») или вывод (
mode
= «w»). Любые другие значения, указанные для
mode
, дают непредсказуемый результат.

В результате выполнения этой функции создается открытый файловый дескриптор канала (pipe), из которого породивший процесс может (

mode
= «r») читать (стандартный поток вывода дочернего процесса
STDOUT_FILENO
) или в который может (
mode
= «w») писать (стандартный поток ввода дочернего процесса
STDIN_FILENO
) стандартным образом, как это делается для типа FILE (в частности, с отработкой ситуации EOF).

Рассмотрим следующий пример. Конечно, посимвольный ввод/вывод — это не лучшее решение, и здесь мы используем его только для простоты:

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 )

cout << (islower(с) ? toupper(с) : c);

Поделиться:
Популярные книги

Приручитель женщин-монстров. Том 3

Дорничев Дмитрий
3. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 3

На границе империй. Том 8. Часть 2

INDIGO
13. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8. Часть 2

Заплатить за все

Зайцева Мария
Не смей меня хотеть
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Заплатить за все

Инкарнатор

Прокофьев Роман Юрьевич
1. Стеллар
Фантастика:
боевая фантастика
рпг
7.30
рейтинг книги
Инкарнатор

Кодекс Охотника. Книга XVI

Винокуров Юрий
16. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVI

Гром над Империей. Часть 1

Машуков Тимур
5. Гром над миром
Фантастика:
фэнтези
5.20
рейтинг книги
Гром над Империей. Часть 1

Идеальный мир для Социопата 7

Сапфир Олег
7. Социопат
Фантастика:
боевая фантастика
6.22
рейтинг книги
Идеальный мир для Социопата 7

Газлайтер. Том 3

Володин Григорий
3. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 3

Защитник

Астахов Евгений Евгеньевич
7. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Защитник

Возвышение Меркурия. Книга 2

Кронос Александр
2. Меркурий
Фантастика:
фэнтези
5.00
рейтинг книги
Возвышение Меркурия. Книга 2

Приручитель женщин-монстров. Том 4

Дорничев Дмитрий
4. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 4

Попаданка в деле, или Ваш любимый доктор - 2

Марей Соня
2. Попаданка в деле, или Ваш любимый доктор
Любовные романы:
любовно-фантастические романы
7.43
рейтинг книги
Попаданка в деле, или Ваш любимый доктор - 2

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Машенька и опер Медведев

Рам Янка
1. Накосячившие опера
Любовные романы:
современные любовные романы
6.40
рейтинг книги
Машенька и опер Медведев