Int child_pid

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

if (child_pid = fork()) {

printf («Это родитель, PID сына %d\n»,

child_pid);

}

else {

printf («Это сын, PID %d\n», getpid ())

выведет на экран примерно следующее:

PID родителя равен 4496

Это родитель, PID сына 8197

Это сын, PID 8197

Последовательный вызов функций fork() и ехес() в UNIX является основным механизмом создания нового процесса.

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

Функция vfork() создает «сына», но затем приостанавливает родительский поток до тех пор, пока «сын» не вызовет функцию ехес() или не завершится (с помощью, например, функции exit()).

Новый процесс наследует дисциплину диспетчеризацию у процесса – родителя.

Изменить (установить) приоритет потока можно функциями setprio(), прочитать – getprio().

Запуск потока.

Любой поток может создать другой поток в том же самом процессе; на это не налагается никаких ограничений (за исключением объема памяти. Наиболее общий путь реализации этого – использование вызова функций POSIX pthread_create():

#include <pthread.h>

Int

pthread_create (pthread_t *thread,

const pthread_attr_t *attr,

void *(*start_routine) (void *),

void *arg);

Функция pthread_create() имеет четыре аргумента:

thread указатель на структуру pthread_t, где хранится идентификатор потока;

attr атрибутная запись;

start_routine подпрограмма, с которой начинается поток;

arg параметр, который передается подпрограмме start_routine

Указатель thread и атрибутная запись ( attr ) — необязательные элементы, и можно передавать вместо них передавать NULL.

Параметр thread может использоваться для хранения идентификатора вновь создаваемого потока:

pthread_t tid;

pthread_create (&tid,...

printf («Новый поток имеет идентификатор %d\n», tid);

Новый поток начинает выполнение с функции start_routine, с параметром arg.

При создании потока он устанавливает некоторые свои атрибуты из структуры с типом данных pthread_attr_t потока-родителя и создает структуру данных pthread_attr_t, копируя туда данные из структуры типа pthread_attr_t потока-родителя.

Структура типа pthread_attr_t следующая:

typedef struct {

int flags;

size_t stacksize;

void *stackaddr;

void (*exitfunc)(void *status);

int policy;

struct sched_param param;

unsigned guardsize;

} pthread_attr_t;

В основном эти поля используются как:

flags –Неисчисляемые (булевы) характеристики потока — например, создается поток как «обособленный» или «синхронизирующий».

stacksize, stackaddr и guardsize –Параметры стека

exitfunc – Функция, выполняемая перед завершением потока,

policy и рarат –Параметры диспетчеризации. В версии QNX6.2 структура param содержит единственный элемент sched_prioriti

Для управления атрибутами потока необходимо прежде инициализировать структуру pthread_attr_t. Для этого предназначена функция pthread_attr_init() (для деинициализации структуры предназначена функция pthread_attr_destroy(), однако она практически не используется.

Примечание: ptread_attr_t attr;

ptread_attr_init (&attr).

Функцию pthread_attr_init() для инициализации атрибутной записи необходимо вызвать до момента ее использования, задействовать ее с помощью соответствующей функции (функций) pthread_attr_set*() и только затем вызвать функцию pthread_create() для создания потока. Изменение атрибутной записи после того, как поток уже создан, не будет иметь никакого действия.

Прочесть элементы атрибутной записи можно с использованием соответствующей функции (функций) pthread_attr_get*()

В зависимости от того, какой атрибут необходимо изменить/прочесть, необходимо подставлять в имя функции pthread_attr_set*() / pthread_attr_get*() соответствующее значения:

Флаги (булевы характеристики) устанавливаются следующими функциями:

pthread_attr_setdetachstate() – устанавливает степень свободы потока, т.е. поток создается как присоединенный (поток-родитель может синхронизироваться по завершению создаваемого потока – задается по умолчанию) или нет – синхронизация не возможна.

pthread_attr_setdetachstate(&attr, PTHREAD_CRATE_JOINABLE ) – синхронизирующий

pthread_attr_setdetachstate(&attr, PTHREAD_CRATE_DETACHED ) – не синхронизирующий

pthread_attr_setdetachstate(&attr, PTHREAD_INHERIT_SHED ) – наследует атрибут потока-родителя (по умолчанию)

pthread_attr_setinheritsched() – устанавливает способ задания параметров диспетчеризации, т.е. создаваемый поток наследует параметры диспетчеризации потока-родителя (по умолчанию либо константой PTHREAD_INHERIT_SHED) или параметры диспетчеризации устанавливаются (константа PTHREAD_EXPLICIT_SHED) функциями pthread_attr_setschedparam() – уровень приоритета и pthread_attr_setschedpolicy () – дисциплина диспетчеризации: карусельная (константой SCHED_RR), FIFO (константой SCHED_ FIFO) или другая (константой SCHED_OTHER). В версии QNX/Neutrino 6.2 параметр SCHED_OTHER интерпретируется как SCHED_RR (карусельная диспетчеризация), а в версии 6.3. – как спорадическая.

В версии 6.3. для установки спорадической диспетчеризации используется также константа SCHED_SPORADIC

pthread_attr_setscope() – устанавливает имеет ли поток масштаб процесса или системы. Масштаб системы означает, что за обладание ресурсами все потоки в системе конкурируют друг с другом; масштаб процесса же означает, что потоки конкурируют за процессор только в пределах «своего» процесса, а диспетчеризацию процессов выполняет ядро. QNX/Neutrino поддерживает для потоков только масштаб системы, и эта функция практически не используется.

Для установки параметров стека служат функции


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: