Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


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




 

Для создания порожденного процесса используется функция fork:

pid_t fork (void).

Тип pid_t определен в <sys/types.h> и соответствует типу int. При успешном выполнении создается порожденный процесс и функция возвращает идентификатор этого порожденного процесса родительскому процессу. Порожденный процесс получает от fork нулевой код возврата.

Как порожденный процесс, так и родительский планируются ядром Unix для выполнения независимо, а очередность запуска этих процессов зависит от реализации ОС. По завершении вызова fork выполнение обоих процессов возобновляется. Возвращаемое значение вызова fork мспользуется для того, чтобы определить, является ли процесс порожденным или родительским.

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

Функция exit завершает процесс. Ее прототип имеет вид:

void exit (int exit_code),

где exit_code – код завершения процесса.

Простейший пример создания нового процесса:

 

#include <iostream.h>

#include <sys/wait.h>

#include <unistd.h>

 

int main()

{ int status;

if (fork())

{ cout << "Child process\n";

exit(0);

};

 

 

cout << "Parent process\n";

}

 

Родительский процесс использует функции wait и waitpid для перехода в режим ожидания завершения порожденного процесса и для выборки его статуса завершения. Прототипы этих функций выглядят так:

 

pid_t wait (int status_p);

pid_t waitpid (pid_t child_pid, int* status_p,

int options).

 

Функция wait приостанавливает выполнение родительского процесса до тех пор, пока один из его порожденных процессов не завершится. Если порожденный процесс уже завершился, функция wait возвратится со статусом завершения порожденного процесса status_p, а возвращаемым значением будет PID порожденного процесса.

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

Для того, чтобы вызывающий процесс изменил свой контекст (регистры, адресное пространство и др.) и выполнил другую программу, используется функция exec. Есть несколько версий этой функции, одна из них execl:

int execl (const char* path, const char* arg, ).

Первый аргумент функции является либо полным путевым именем, либо именем файла программы, подлежащей исполнению. Аргументы arg являются аргументами для программы, вызванной функцией exec. Они отображаются в переменную argv функции main новой программы. При этом arg отображается в argv[0], значение, указанное после arg, - в argv[1] и т. д. Список аргументов заканчивается нулевым значением.

 

Пример.

 

#include <stdio.h>

#include <unistd.h>

 

int main()

{

char s1[8]="string1", s2[4]="string2";

execl ("./b.out", s1, s2, 0);

return 0;

}

 

Здесь вызывается программа b.out, скомпилированная из файла

 

#include <stdio.h>

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

{

printf("%s\n",argv[0]);

printf("%s\n",argv[1]);

return 0;

}

 

В результате выполнения примера будут выведены строки string1

string2

 

Большинство программ вызывают exec в порожденном процессе, так как выполнение родительского процесса после вызова exec желательно продолжить. Однако программа может вызвать exec без fork, аfork без exec.


Программные каналы

 

Функция pipe создает прораммный канал между двумя взаимосвязанными процессами. В частности эта функция создает файл канала, который служит в качестве временного буфера и используется для того, чтобы вызывающий процесс мог записывать и считывать данные другого процесса. Файлу канала имя не присваивается, поэтому он называется неименованным каналом. Прототип функции:

int pipe (int fifo[2]).

Аргумент fifo является массивом, состоящим из двух целых чисел, присваиваемых ему интерфейсом pipe. В болшинстве систем Unix канал является однонаправленным, т. е. для чтения данных из канала процесс использует дескриптор файла fifo[0], а для записи данных в канал – другой дескриптор файла fifo[1].

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

 

#include <iostream.h>

#include <stdio.h>

#include <sys/wait.h>

#include <unistd.h>

 

int main()

{

int child_pid;

int fifo[2], status;

int sf=sizeof(float);

float buf1=2;

 

pipe(fifo);

write(fifo[1],&buf1,sf);

 

child_pid=fork();

if (child_pid==0)

{ float buf2;

read(fifo[0],&buf2,sf);

buf2=buf2+1;

write(fifo[1],&buf2,sf);

exit(0);

};

 

wait(&status);

read(fifo[0],&buf1,sf);

cout << "buf1=" << buf1;

}

 

.

 





Поделиться с друзьями:


Дата добавления: 2017-01-28; Мы поможем в написании ваших работ!; просмотров: 479 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Люди избавились бы от половины своих неприятностей, если бы договорились о значении слов. © Рене Декарт
==> читать все изречения...

2514 - | 2318 -


© 2015-2025 lektsii.org - Контакты - Последнее добавление

Ген: 0.01 с.