Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект Лекций ПСРВ.doc
Скачиваний:
81
Добавлен:
12.02.2016
Размер:
2.73 Mб
Скачать

7.3.4. Функция fork()

Функция fork() создает новый (дочерний) процесс, являющийся точной копией процесса, его породившего (родительского). При этом дочерний процесс имеет уникальный PID. Идентичные дочерние процессы могут иметь разных родителей их породивших. Дочерний процесс имеет собственную копию дескрипторов файла родительского процесса, ссылающийся на тот же самый открытый файл родителя, а также собственные копии потоков к каталогам, открытых родительским процессом. Значения tms_utime, tms_stime, tms_cutime, и tms_cstime дочернего процесса установлены в 0. Блокировки файла, предварительно установленные родителем, дочерним процессом не наследуются. Задержанные звонки таймера очищаются для дочернего процесса. Набор задерживаемых сигналов для дочернего процесса инициализируется как пустой. Оба процесса продолжают выполняться от функции fork().

Объявление функции имеет вид:

#include <sys/types.h>

#include <process.h>

 

pid_t fork(void);

 

В дочернем процессе функция возвращает 0, а в родительском - PID дочернего процесса. В случае ошибки fork() возвращает -1 родительскому процессу и устанавливает errno.

 

Пример:

 

#include <stdio.h>

#include <sys/types.h>

#include <process.h>

 

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

int retval;

printf("Это родительский процесс\n");

fflush(stdout);

retval = fork(void);

printf("Кто это сказал?\n");

return EXIT_SUCCESS;

}

После вызова fork() оба процесса выполнят второй вызов printf(). Данное приложение выведет на экран следующее:

Это родительский процесс

Кто это сказал?

Кто это сказал?

Функция fflush, которая объявлена в заглавном файле ' stdio.h ' , вызывается для того, что бы сбросить буферизированный вывод.

Функция: int fflush (FILE *stream).

Эта функция заставляет любой буферизированный вывод на потоке дописываться в файл. Эти функции возвращают EOF, если происходит ошибка записи, и нуль в другом случае.

Чтобы различить эти два процесса необходимо проанализировать возвращаемое функцией fork() значение в retval. В дочернем процессе retval будет иметь нулевое значение, а в родительском - содержать PID дочернего процесса. Для пояснения рассмотрим фрагмент программы:

printf("PID родителя равен %d\n",getpid());

fflush(stdout);

if(retval = fork(void)){

printf("Это родитель, PID дочернего процесса %d\n", retval);

}else{

printf("Это дочерний процесс, PID %d\n",getpid());

}

ID процесса получается в результате вызова функции pid_t getpid (void), определеннойв файле " unistd.h ". (функция getppid возвращает ID родительского процесса)

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

7.3.5. Функция vfork()

Функция vfork() создает новый процесс, как и функция fork(), но в разделяемом адресном пространстве, и блокирует родительский процесс до тех пор, пока дочерний процесс не завершится или не вызовет функцию семейства exec*().

Объявление функции имеет вид:

 #include <sys/types.h>

#include <process.h>

 

pid_t vfork(void);

7.4. Организация взаимодействия между процессами

Процесс в QNX обеспечивает нитям интерфейс взаимодействия с нитями других процессами. Ключевым механизмом этого взаимодействия является механизм обмена сообщениями. При передаче сообщений между процессами один процесс (нити которого принимают сообщения) считается сервером, а другой (нити которого посылают сообщения) - клиентом. Поэтому механизм обмена сообщениями в QNX называют моделью "клиент/сервер". Один и тот же процесс может одновременно обеспечивать, как прием, так и посылку сообщений, т.е. выполнять функции и клиента и сервера. В частности, процесс может обеспечивать взаимодействие собственных нитей между собой посредством сообщений.

Для приема сообщений некоторая нить сервера должна создать объект, называемый каналом. В сервере может быть создан один и более каналов. В свою очередь, чтобы нити клиента получили возможность посылать сообщения в канал сервера, некоторой нитью должен быть создан объект, называемый соединением (связью) с каналом (установить соединение с каналом). С одним каналом сервера может быть установлено произвольное количество соединений одним или несколькими клиентами. Нити процессов могут создавать и уничтожать каналы и соединения по мере необходимости.