Состояния процесса в МОС презентация

Содержание

Петрозаводский госуниверситет, А. В. Соловьев, 2007 СЕТЕВЫЕ ТЕХНОЛОГИИ Проблема Серверу необходимо обслуживать множество клиентов. Клиенту, как правило, приходится взаимодействовать с пользователем и с сервером. Каждая операция ввода-вывода может

Слайд 1
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Состояния процесса в МОС
Rev. 1.01

/ 5.11.2007

RUN

READY

WAIT

1

2

Пользовательская
фаза

Фаза ядра ОС

3

4

5


Слайд 2
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Проблема
Серверу необходимо обслуживать множество клиентов.

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

Необходимо обеспечить возможность выполнения операций ввода-вывода несколькими дескрипторами файлов* (в любой момент времени).

* Everything in Unix is a file


Слайд 3
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Способы организации вв/выв
Синхронный ввод-вывод (блокирующий)
Неблокирующий ввод-вывод
С

возможностью уведомления о состоянии готовности (level-triggered readiness notification)

С возможностью уведомления об изменении состоянии готовности (readiness change notification)

Асинхронный ввод-вывод (с уведомлением о завершении операции)


Слайд 4
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Синхронный ввод/вывод
Обслуживанием каждого дескриптора файла

занимается отдельный процесс (отдельная нить).

while (true) {
client_sock=accept(serv_sock,…);
fork();
close(client_sock);
waitpid(…);
}



close(serv_sock);
read(client_sock,…);
write(client_sock,…);
close(client_sock);
exit();

client_sock

client_sock

client_sock

serv_sock

Особенности:
не требуется мультиплексирование ввода-вывода
проблемы синхронизации и взаимодействия
большая ресурсоёмкость → проблема C10k


возможна параллельная обработка запросов (SMP), нет проблемы «длинных запросов»


Слайд 5i = 0;
while (true) {
len = read(client_socks[i],…);
if

(len == 0) { /* соединение закрыто */ }
if (len < 0 && errno != EAGAIN) { /* ошибка */ }
if (len > 0) serve_client(i);
new_sock = accept(serv_sock,…);
if (new_sock >= 0) {
fcntl(new_sock, F_SETFL, O_NONBLOCK);
/* добавляем нов. сокет в client_socks[] */
}

i = ++i % num_socks;
}


Петрозаводский госуниверситет, А. В. Соловьев, 2007

СЕТЕВЫЕ ТЕХНОЛОГИИ



Неблокирующий ввод/вывод

Системный вызов возвращается сразу с кодом ошибки EAGAIN (в BSD – EWOULDBLOCK). Необходимо периодически повторять вызов до тех пор, пока он не завершится успешно либо возникнет другая ошибка.

client_sock

client_sock

client_sock

Особенности:
холостые циклы → снижение производительности системы
единовременно обслуживается только 1 клиент

serv_sock


Слайд 6
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Level-triggered notification
Процесс запрашивает у ядра

ОС, возможен ли ввод/вывод без блокировки для какого-либо дескриптора из набора. Если ни один из дескрипторов «не готов», вызов может блокировать процесс или вернуться сразу.

while (true) {
/* подготовка к вызову */
num = select(…); /* или poll(…) */
if (num > 0) {
/* проход по набору дескрипторов,
обслуживание «готовых» */
}
}

Особенности:
ограничение FD_SETSIZE для select()
единовременно обслуживается только один клиент (неэффективно для SMP)


client_sock

client_sock

client_sock

serv_sock


Слайд 7ОС

Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Edge-triggered notification

Для дескрипторов устанавливается флаг оповещения о готовности по сигналу. При смене состояния дескриптора с «неготового» на «готовое», при котором возможен ввод/вывод без блокировки, процессу посылается сигнал. Дальнейшие оповещения не происходят, пока дескриптор снова не будет переведён в «неготовое» состояние.

/* подготовка к вызову */
sigaction(…);
while (true) {
sigsuspend(…);
}

Особенности:
проблемы синхронизации доступа к данным
сложности отладки (код обработчика должен быть тщательно продуман)
единовременно обслуживается только один клиент (неэффективно для SMP)

client_sock

client_sock

client_sock

serv_sock

void io_handler(…) {
/* получем номер дескриптора
и обслуживаем соответствующего клиента */
}

сигнал


Слайд 8
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Асинхронный ввод/вывод
Особенности:
проблемы синхронизации доступа

к данным
сложности отладки (код обработчика должен быть тщательно продуман)
единовременно обслуживается только один клиент (неэффективно для SMP)

Операции ввода/вывода сразу возвращаются в вызвавший их процесс. О завер-шении операции ОС уведомляет процесс через сигнал (в Linux; сообщение – в Windows) либо через специальный сигнализирующий объект (Windows).

В Linux интерфейс AIO не позволяет работать с сокетами.

В Windows сокеты и файлы имеют разные механизмы асинхронного ввода/вывода. Для файлов и объектов, открываемых с помощью CreateFile(), асинхронный ввод/вывод реализуется при помощи Overlapped I/O, для сокетов – реализован в Winsock в виде отдельного набора функций.


Слайд 9
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Работа с процессами
Создание дочернего процесса
#include


#include
pid_t fork(void);

При ошибке функция возвращает -1, дочерний процесс при этом не создаётся.
В родительский процесс эта функция возвращает PID нового процесса.
В дочерний процесс эта функция возвращает 0.
Пример:
pid_t new_pid;
new_pid=fork();
if (new_pid == -1) { /* ошибка */ }
if (new_pid == 0) {
/* дочерний процесс */
}
else {
/* родительский процесс */
}

Слайд 10
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Работа с процессами
Завершение процесса
#include
void

exit(int status);
Функция не возвращается в вызвавший её процесс.
В качестве статуса выхода используются только младшие 8 бит status. Значение 0 (EXIT_SUCCESS) означает успешное завершение процесса. Ненулевое значение (обычно EXIT_FAILURE=1) передаётся родительскому процессу в том случае, если процесс завершается из-за возникновения ошибки.
После выполнения exit() ОС может поступить следующим образом:
если родительский процесс установил для сигнала SIGCHLD в качестве обработчика SIG_IGN или задал флаг SA_NOCLDWAIT, значение status отбрасывается, завершаемый процесс уничтожается;
если родительский процесс ожидал завершения потомка при помощи wait() или подобной функции, он возобновляется и получает статус завершения status, завершаемый процесс уничтожается.
в противном случае завершаемый процесс переводится в состояние “zombie”, в котором он представляет собой контейнер для хранения значения status до тех пор, пока родительский процесс не сделает wait().

Слайд 11
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Работа с процессами
Ожидание завершения дочернего

процесса
#include
#include
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

Результат: PID завершившегося потомка. При ошибке функции возвращают -1. Для waitpid() возможен результат 0, означающий, что ни один потомок не завершился.
Ожидаем pid: -1 – любого потомка, >0 – конкретного потомка.
status: адрес переменной для хранения статуса выхода потомка (м.б. NULL)
options: WNOHANG – вернуть 0, если ни один потомок не завершился


Слайд 12
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Работа с процессами
Получение PID и

PPID

#include
#include

pid_t getpid(void);
pid_t getppid(void);


Слайд 13
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Работа с процессами
Запуск программы
#include
int

execve(
const char *filename, /*имя файла*/
char *const argv[], /*аргументы ком.строки*/
char *const envp[]); /*среда окружения*/
При ошибке функция возвращает -1. В случае успеха функция не возвращается в вызвавший её процесс, при этом содержимое сегментов кода, стека и данных меняется со старого на новое. Запущенная программа имеет такой же PID и сохраняет открытыми все те файловые дескрипторы, для которых не был установлен флаг FD_CLOEXEC. Для filename поиск в PATH не осуществляется!
В массивах argv и envp последний элемент должен быть NULL. argv[0] – имя программы. envp содержит пары значений переменных окружения key=value.
Пример:
char *const argv[] = {"ps", "aux", NULL};
char *const envp[] = {NULL};
if (execve("/bin/ps", argv, envp)) { /* ошибка*/ }

Слайд 14
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Работа с процессами
«Демонизация» (пример)
#include
#include


#include
pid_t pid;
int main() {
pid = fork();
if (pid == -1) { /* ошибка */ }
if (pid > 0) { /* родительский процесс */
sleep(1);
exit(EXIT_SUCCESS);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
setsid();
/* далее процесс работает как "демон" */
}

Слайд 15
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


POSIX Threads
Библиотека pthread (POSIX Threads)

предоставляет средства работы с нитями (threads). При компиляции программ, использующих нити, необходимо указать редактору связей (компоновщику) на использование данной библиотеки:
gcc –lpthread my_prog.c

Основные функции
#include
int pthread_create(
pthread_t *thread,
pthread_attr_t *attr,
void* (*start_routine)(void*),
void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread_t th, void **thread_return);
int pthread_detach(pthread_t th);
int pthread_cancel(pthread_t th);
pthread_t pthread_self(void);

Слайд 16
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


POSIX Threads
Атрибуты нитей
#include

int pthread_attr_init(pthread_attr_t

*attr);
int pthread_attr_destroy(pthread_attr_t *attr);
int pthread_attr_setaname(pthread_attr_t *attr,int value);
aname=detachstate:
PTHREAD_CREATE_JOINABLE, PTHREAD_CREATE_DETACHED
aname=shedpolicy: (требуются привилегии рута)
SCHED_OTHER (обычная), SCHED_RR (RT, round-robin), SCHED_FIFO (RT, fifo)
aname=shedparam: (можно менять «на лету») целое число, по умолчанию 0.

int pthread_setcancelstate(int state, int *oldstate);
state: PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE

int pthread_setcanceltype(int type, int *oldtype);
type: PTHREAD_CANCEL_DEFERRED, PTHREAD_CANCEL_ASYNCHRONOUS


Слайд 17
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


POSIX Threads
Пример:
#include

pthread_t th;
void* child_th(void*);

int

main() {
pthread_create(&th, NULL, &child_th, NULL);
/* родительская нить занимается своими делами */
pthread_join(th, NULL);
return 0;
}

void* child_th(void *tmp) {
/* дочерняя нить делает своё дело */
pthread_exit(NULL);
}

Слайд 18
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Синхронное мультиплексирование ввода/вывода
#include

/* POSIX 1003.1-2001 */
int select(
int n, /*макс. номер дескриптора*/
fd_set *readfds, /*дескрипторы для чтения*/
fd_set *writefds, /*дескрипторы для записи*/
fd_set *exceptfds, /*дескрипторы для искл.*/
struct timeval *timeout); /*таймаут*/
При ошибке функция возвращает -1. В случае успеха функция возвращает количество дескрипторов, готовых к операциям без блокировки. Функция возвращает 0, если истекло время ожидания (timeout).
Ошибки:
EBADF – в набор включён недействительный дескриптор
EINTR – вызов был прерван сигналом
EINVAL – некорректные значения n или timeout
ENOMEM – не хватает памяти для выполнения операции

Слайд 19
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Перед вызовом select() необходимо

заполнить битовые поля fd_set. При успешном возврате из select() в этих битовых полях остаются дескрипторы, для которых
readfds: возможно чтение без блокировки, в том числе ноль байт (EOF),
для сокетов в режиме прослушивания – возможен ли accept() без блокировки
writefds: возможна ли запись без блокировки,
для сокетов в режиме соединения (connect) – соединение установлено
exceptfds: для сокетов – наличие пакетов с пометкой URG (out-of-band data)

Битовое поле fd_set может иметь максимальную длину FD_SETSIZE. Дескрипторы с номером больше FD_SETSIZE не могут быть помещены в битовое поле FD_SETSIZE (обычно FD_SETSIZE=1024).

Аргумент n – это максимальный номер дескриптора + 1. Обычно в качестве этого параметра передают значение FD_SETSIZE.

Слайд 20
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
timeout:
Если timeout NULL, то

select() может блокироваться на неопределённое время – до «готовности» одного из заданных в наборах дескрипторов либо до получения сигнала.

#include /* или */
struct timeval {
long tv_sec; /* секунды */
long tv_usec; /* микросекунды */
};

Если timeout.tv_sec=0 и timeout.tv_usec=0, то select() возвращается сразу же, информируя, есть ли «готовые» дескрипторы.

В Linux при возврате из select() timeout содержит оставшееся до истечения таймаута время. В других системах такое поведение не предусмотрено. POSIX рекомендует считать, что при возврате из select() значение timeout не определено (т. е. его нельзя использовать повторно).

Слайд 21
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Манипулирование битовыми полями fd_set
#include

/* POSIX 1003.1-2001 */

/* очистка набора fds: */
void FD_ZERO(fd_set *fds);

/* добавление дескриптора fd в набор: */
void FD_SET(int fd, fd_set *fds);

/* удаление дескриптора fd из набора: */
void FD_CLR(int fd, fd_set *fds);

/* проверка на наличие дескриптора fd в наборе: */
int FD_ISSET(int fd, const fd_set *fds);

Слайд 22
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Пример:
fd_set rfds;
struct timeval tv;
int

n, i;
while (1) {
FD_ZERO(&rfds);
for (i = 0; i < num; i++) FD_SET(fd[i], &rfds);
tv.tv_sec = 5; /* ждать не более 5 сек */
tv.tv_usec = 0;
n = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
if (n == -1) { /* ошибка */};
else if (n > 0) {
for (i=0; i /* осуществляем ввод-вывод */
}
}
else if (n == 0) { /* таймаут истёк */ }
}

Слайд 23
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Синхронное мультиплексирование ввода/вывода

#include

int

poll(
struct pollfd *ufds, /*массив ожидаемых событий*/
unsigned nfds, /*кол-во эл-тов в ufds*/
int timeout); /*таймаут в мс*/

При ошибке функция возвращает -1. В случае успеха функция возвращает количество дескрипторов, готовых к операциям без блокировки. Функция возвращает 0, если истекло время ожидания (timeout).

Отрицательный timeout означает ждать «до победы».



Слайд 24
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
struct pollfd {
int fd; /*дескриптор

файла*/
short events; /*запрашиваемое событие*/
short revents; /*произошедшее событие*/
};

events, revents: набор битовых масок, объединяемых OR
POLLIN – возможно чтение без блокировки
POLLPRI – появились пакеты с пометкой URG (out-of-band data)
POLLOUT – возможна запись без блокировки
POLLERR – произошла ошибка
POLLHUP – разрыв связи
POLLNVAL – некорректное значение fd



Слайд 25
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Пример:
struct pollfd fds[num];
int n,

i;
while (1) {
for (i = 0; i < num; i++) {
fds[i].fd = fd[i];
fds[i].events = POLLIN;
fds[i].revents = 0;
}
n = poll(fds, num, -1);
if (n == -1) { /* ошибка */};
else if (n > 0) {
for (i=0; i /* осуществляем ввод-вывод */
}
}
}

Слайд 26
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Разное
Определить, сколько байт доступно для

чтения без блокировки
#include
void ioctl(int fd, int request, ...);
request = FIONREAD
void ioctl(int fd, FIONREAD, int *size);

#include
#include
int fcntl(int fd, int cmd, long arg);

Перевести дескриптор в неблокирующий режим
fcntl(fd, F_SETFL, O_NONBLOCK);

Включить оповещение о готовности по сигналу
fcntl(fd, F_SETFL, O_ASYNC);
fcntl(fd, F_SETSIG, signum);
fcntl(fd, F_SETOWN, pid);

Слайд 27
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы (общие сведения)
Сигнал – это

вид средств межпроцессного обмена, использующийся в Unix-подобных и/или POSIX-совместимых ОС. Сигнал представляет собой асинхронное оповещение о некотором событии, посылаемое процессу.
Источники событий:
действия пользователя (CTRL-C, CTRL-Z, CTRL-\)
исключения процессора (деление на 0, GPF, …)
вызов kill()
событие от ядра (SIGPIPE, SIGIO, …)
Реакция на сигнал:
вызывается обработчик, установленный процессом (не для всех сигналов)
вызывается стандартный обработчик
сигнал игнорируется
Процесс может блокировать сигнал (отложить обработку сигнала).
Особенности:
возможны race conditions, поэтому необходимо обеспечивать синхронизацию доступа к данным в программе
сигнал может прервать системный вызов, что делать в таком случае – остаётся на усмотрение программиста («непрозрачный» рестарт)

Слайд 28
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы ANSI C
Установка обработчика сигнала
#include


sighandler_t signal(int signum, signahdler_t action);

action: функция обработчика
void HANDLER(int signum)
SIG_DFL /* стандартный обработчик */
SIG_IGN /* игнорировать сигнал */
Функция возвращает предыдущий способ обработки указанного сигнала или SIG_ERR при ошибке.

Ожидание сигнала
#include
int pause(void);
Функция всегда возвращает -1, при этом errno=EINTR.

Слайд 29
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы ANSI C
Генерация сигнала

#include
#include



int raise(int signum);
int kill(pid_t pid, int signum)

Функции возвращает 0 при успешном завершении или -1 при ошибке.

Слайд 30
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы POSIX
#include
Установка обработчика сигнала
int

sigaction(int signum, /*номер сигнала*/
const struct sigaction *act,/*действие*/
struct sigaction *oldact); /*предыдущее действие*/

Установка маски блокируемых сигналов
int sigprocmask(int how, /*SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK*/
const sigset_t *set, /*набор сигналов*/
segset_t *oldset); /*предыдущий набор*/

Получить отложенные на данный момент сигналы
int sigpending(sigset_t *set);

Функции возвращают -1 при ошибке или 0 при успешном завершении.


Слайд 31
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы POSIX
struct sigaction {
void (*sa_handler)(int);
void

(*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void); /*obsolete*/
};
Не следует задавать и sa_handler, и sa_sigaction – только что-нибудь одно.
В дополнение к маске сигналов sa_mask блокируются сигналы того же типа.
sa_flags:
SA_ONESHOT (SA_RESETHAND) – при первом же вызове обработчика сменить действие для сигнала на SIG_DFL
SA_RESTART - если сигнал приходит во время исполнения системного вызова, то вызов рестартует при нормальном возврате из обработчика (в противном случае будет EINTR)
SA_NOMASK (SA_NODEFER) – сигналы этого типа не блокируются при вызове обработчика
SA_SIGINFO – обработчик сигнала требует 3 аргумента, а не 1 (sa_sigaction)


Слайд 32
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы POSIX
Манипуляции с набором сигналов

(sigset_t)
#include

Очистить набор сигналов set
int sigemptyset(sigset_t *set);

Внести все сигналы в набор set
int sigfillset(sigset_t *set);

Добавить сигнал signum к набору set
int sigaddset(sigset_t *set, int signum);

Удалить сигнал signum из набора set
int sigdelset(sigset_t *set, int signum);

Проверить, есть ли сигнал signum в наборе set (0 – нет, 1 – есть, -1 – ошибка)
int sigismember(const sigset_t *set, int signum);

Слайд 33
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы POSIX
Функция обработчика сигналов

void HANDLER(int

signum, siginfo_t *sinfo, void *addinfo);

struct siginfo_t {
int si_signo; /*номер сигнала*/
int si_errno; /*код ошибки*/
int si_code; /*код (причина) сигнала*/
pid_t si_pid; /*PID процесса, пославшего сигнал*/
uid_t si_uid; /*UID процесса, пославшего сигнал*/
/* ... */
int si_band; /*событие (аналог pollfd.revents)*/
int si_fd; /*дескриптор файла*/
};

Слайд 34
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы POSIX
Ожидание сигнала
#include
int sigsuspend(const

sigset_t *mask);
mask – маска блокируемых на время ожидания сигналов

int sigwaitinfo(const sigset_t *set, siginfo_t *info);
int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec timeout);
set – маска ожидаемых сигналов
struct timespec {
long tv_sec; /*секунды*/
long tv_nsec; /*наносекунды*/
};

Генерация сигнала
int sigqueue(pid_t pid, int signum, const union sigval value);


Слайд 35
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Сигналы RT
Стандартные сигналы «сливаются»
Если в

то время, пока сигнал заблокирован или процесс не находился в состоянии “RUN”, приходит ещё один сигнал того же типа, после деблокирования сигнала обработчик этого сигнала будет вызван лишь один раз.

Сигналы «реального времени» (kernel 2.4.x)
Сигналы с номером SIGRTMIN ≤ signum ≤ SIGRTMAX могут образовывать очередь. Если в то время, пока сигнал заблокирован, приходит ещё один сигнал того же типа, после деблокирования сигнала обработчик этого сигнала будет вызван столько раз, сколько сигналов попало в очередь.
Очередь сигналов может переполнится. При этом генерируется сигнал SIGIO.


Слайд 36
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
#include (kernel 2.6.x)

Интерфейс epoll

предоставляет как возможность оповещения типа level-triggered, так и edge-triggered, причём способ работы с дескрипторами в последнем случае такой же, как и при традиционном синхронном мультиплексировании ввода-вывода.

Создание дескриптора epoll
int epoll_create(int size);

Управление дескриптором epoll
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

Ожидание дескриптора epoll
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

Слайд 37
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Создание дескриптора epoll

int epoll_create(int

size);

size - размер набора дескрипторов, обслуживаемых epoll (рекомендуемое, но не максимальное значение)

При успешном завершении функция возвращает номер дескриптора epoll (положительное число). При ошибке – -1.

Дескриптор, созданный вызовом epoll_create() должен быть закрыт при помощи close().

Слайд 38
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Управление дескриптором epoll
int epoll_ctl(int

epfd, /*дескриптор epoll*/
int op, /*операция*/
int fd, /*дескриптор файла*/
struct epoll_event *event);/*события*/
op: EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL
struct epoll_event {
__uint32_t events; /*события*/
epoll_data_t data; /*данные пользователя*/
};
events: EPOLLIN (чтение), EPOLLOUT (запись), EPOLLPRI (urgent), EPOLLERR (ошибка), EPOLLHUP (разрыв соединения),
EPOLLET – оповещение типа edge-triggered,
EPOLLONESHOT – доставка только одного оповещения.
union epoll_data_t {/*Поле для хранения вспомог. данных*/
void *ptr; /*например, какого-нибудь указателя*/
int fd; /*или дескриптора файла*/
/* ... */
};

Слайд 39
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Ожидание дескриптора epoll

int epoll_wait(int

epfd, /*дескриптор epoll*/
struct epoll_event *events,/*массив событий*/
int maxevents, /*размер массива*/
int timeout); /*таймаут (мс)*/

Перед вызовом epoll_wait() надо отвести место под массив событий events и указать в вызове максимальное кол-во событий maxevents > 0, которое может принять ваш массив. Поле events[i].events будет содержать фактически произошедшее событие, а поле events[i].data – указанные пользователем данные (указатель ptr, или файловый дексриптор fd, или …). Если timeout == -1, то ожидание событий будет с бесконечным таймаутом.

Функция возвращает количество дескрипторов, по которым зафиксировано событие (кол-во заполненных элементов в массиве events). Ноль означает, что за время timeout (мс) запрошенных событий не возникло. При ошибке возвращается -1.

Слайд 40
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Edge-triggered notification
Особенности работы с оповещениями

типа ET

«готовность» дескриптора может наступить до того, как будет включен механизм оповещения типа ET
дескриптор может остаться в «готовом» состоянии и после обработки события

В этом случае последующая операция ожидания события на этом дескрипторе может быть заблокирована до бесконечности.

Решение:
дескриптор должен быть в неблокирующем режиме
до того, как начать ожидание оповещения типа ET необходимо сделать read (write) и убедиться, что возвращается EAGAIN

Слайд 41
Петрозаводский госуниверситет, А. В. Соловьев, 2007
СЕТЕВЫЕ ТЕХНОЛОГИИ


Мультиплексирование вв/выв
Пример:
struct epoll_event evs[num];
int n,

i, ep;
ep = epoll_create(num);
if (ep == -1) { /*ошибка*/ }
for (i=0; i evs[0].events = EPOLLIN;
evs[0].data.fd = fd[i];
epoll_ctl(ep, EPOLL_CTL_ADD, fd[i], evs);
}
while (1) {
n = epoll_wait(ep, evs, num, -1);
if (n == -1) { /*ошибка*/};
else for (i=0; i do_io(evs[i]); /*осуществляем ввод-вывод*/
}
}

Обратная связь

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

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

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


Для правообладателей

Яндекс.Метрика