Досрочное завершение клиента

Досрочное завершение клиента

Посмотрим, каким образом процедура сервера получает уведомление о досрочном завершении клиента. Пpoгрaммa-клиeнт приведена в листинге 15.25.

Листинг 15.25. Клиент, досрочно завершающий работу после вызова door_call

//doors/clientintr4.c

1  #include "unpipc.h"

2  int

3  main(int argc, char **argv)

4  {

5   int fd;

6   long ival, oval;

7   door_arg_t arg;

8   if (argc != 3)

9    err_quit("usage: clientintr4 <server-pathname> <integer-value>");

10  fd = Open(argv[1], O_RDWR); /* открываем дверь */

11  /* подготовка аргументов и указателя на результаты */

12  ival = atol(argv[2]);

13  arg.data_ptr = (char*)&ival; /* аргументы */

14  arg.data_size = sizeof(long); /* размер аргументов */

15  arg.desc_ptr = NULL;

16  arg.desc_num = 0;

17  arg.rbuf = (char*)&oval; /* возвращаемые данные */

18  arg.rsize = sizeof(long); /* размер возвращаемых данных */

19  /* вызов процедуры сервера и вывод результата */

20  alarm(3);

21  Door_call(fd, &arg);

22  printf("result: %ld ", oval);

23  exit(0);

24 }

20 Единственное изменение заключается в добавлении вызова alarm(3) перед door_call. Эта функция приводит к отправке сигнала SIGALRM через три секунды после вызова, но, поскольку мы его не перехватываем, это приводит к завершению процесса. Поэтому клиент завершится до возврата из door_call, потому что в процедуру сервера вставлена шестисекундная пауза.

В листинге 15.26 приведен текст процедуры сервера и обработчик отмены потока.

Листинг 15.26. Процедура сервера, обрабатывающая досрочное завершение клиента

//doors/serverintr4.с

1  #include "unpipc.h"

2  void

3  servproc_cleanup(void *arg)

4  {

5   printf("servproc cancelled, thread id %ld ", pr_thread_id(NULL));

6  }

7  void

8  servproc(void *cookie, char *dataptr, size_t datasize,

9   door_desc_t *descptr, size_t ndesc)

10 {

11  int oldstate, junk;

12  long arg, result;

13  Pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);

14  pthread_cleanup_push(servproc_cleanup, NULL);

15  sleep(6);

16  arg = *((long*)dataptr);

17  result = arg * arg;

18  pthread_cleanup_pop(0);

19  Pthread_setcancelstate(oldstate, &junk);

20  Door_return((char*)&result, sizeof(result), NULL, 0);

21 }

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

? если поток отключил возможность отмены, ничего не происходит и поток выполняется до завершения (вызов door_return), а результаты сбрасываются;

? если возможность отмены включена, вызываются обработчики отмены потока, а затем он завершает работу.

В тексте процедуры сервера мы сначала вызвали pthread_setcancelstate для включения возможности отмены потока, потому что по умолчанию при создании новых потоков библиотекой возможность их отмены отключается. Эта функция сохраняет текущее состояние потока в переменной oldstate, и мы восстанавливаем его в конце функции. Затем мы вызываем pthread_cleanup_push для регистрации нашего обработчика отмены servproc_cleanup. Эта функция только выводит идентификатор отмененного потока, но вообще она может выполнять все необходимое для корректного завершения процедуры сервера (разблокировать исключения и т. п.). После возвращения из обработчика поток завершается.

В текст процедуры сервера мы добавляем 6-секундную паузу, чтобы клиент мог успешно завершить работу в вызове door_call.

Запустив клиент дважды, мы увидим сообщение интерпретатора Alarm clock при завершении процесса сигналом SIGALRM:

solaris % clientintr4 /tmp/door4 44

Alarm Clock

solaris % clientintr4 /tmp/door4 44

Alarm Clock

Посмотрим, что при этом выводит сервер. Каждый раз при досрочном завершении клиента поток процедуры сервера действительно отменяется и вызывается обработчик отмены потока: 

solaris % serverintr4 /tmp/door4

servproc canceled, thread id 4

servproc canceled, thread id 5

Цель, с которой мы вызываем программу-клиент дважды, — показать, что после завершения потока с идентификатором 4 библиотека создает новый поток (с идентификатором 5) для обработки второго запроса клиента.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Завершение

Из книги Давайте создадим компилятор! автора Креншоу Джек

Завершение Наконец-то, в этой главе мы узнали как работать с переменными (и литералами) различных типов. Как вы можете видеть, это не было слишком сложно. Фактически, в каком-то отношении большая часть кода выглядит даже еще проще, чем это было в более ранних программах.


7.1.5 Завершение

Из книги Процессы жизненного цикла программных средств автора Автор неизвестен


Завершение сеанса

Из книги Windows Vista автора Вавилов Сергей

Завершение сеанса В нижней части правого столбца меню Пуск располагаются кнопки, отвечающие за завершение сеанса работы Windows и выключение компьютера. В Windows Vista кнопка Питание в меню Пуск выполняет совершенно иную функцию, нежели в Windows XP: она не выключает компьютер, а


15.11. Досрочное завершение клиента или сервера

Из книги UNIX: взаимодействие процессов автора Стивенс Уильям Ричард

15.11. Досрочное завершение клиента или сервера В наших примерах до настоящего момента предполагалось, что в процессе работы клиента и сервера не возникает непредусмотренных ситуаций. Посмотрим, что произойдет, если у клиента или сервера возникнут ошибки. В случае если


Досрочное завершение сервера

Из книги Инфраструктуры открытых ключей автора Полянская Ольга Юрьевна

Досрочное завершение сервера Если клиент блокируется в вызове door_call, ожидая получения результатов, ему нужно каким-то образом получить уведомление о завершении потока сервера по какой-либо причине. Посмотрим, что происходит в этом случае, прервав работу сервера вызовом


16.7. Досрочное завершение сервера или клиента

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

16.7. Досрочное завершение сервера или клиента Рассмотрим, что произойдет в случае досрочного завершения клиента или сервера при использовании транспортного протокола TCP. Поскольку протокол UDP не подразумевает установку соединения, при завершении процесса его


Досрочное завершение сервера

Из книги Язык Си - руководство для начинающих автора Прата Стивен

Досрочное завершение сервера Завершим работу сервера досрочно, в процессе обработки запроса клиента. Единственное изменение в программе-клиенте будет заключаться в удалении аргумента tcp из вызова clnt_call в листинге 16.2 и включении протокола в набор аргументов командной


Досрочное завершение клиента

Из книги Linux и UNIX: программирование в shell. Руководство разработчика. автора Тейнсли Дэвид

Досрочное завершение клиента Если клиент, использующий TCP, завершает работу в процессе выполнения процедуры RPC, серверу отправляется пакет FIN. Мы хотим узнать, как библиотека сервера реагирует на этот пакет и уведомляет об этом процедуру сервера. (В разделе 15.11 мы говорили,


Завершение

Из книги Как тестируют в Google автора Уиттакер Джеймс

Завершение Если все списки САС проанализированы, а переменная состояния маски причины не показывает, что все причины аннулирования проверены, то переменная состояния статуса сертификата принимает значение "не определен". Большинство приложений будет реагировать на


Завершение транзакций

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

Завершение транзакций Транзакция завершается, когда клиентское приложение подтверждает ее или отменяет. Если оператор COMMIT или вызов эквивалентной функции API isc_commit_ transaction не будут успешными, то транзакция не будет подтверждена. Если транзакция, которая не может быть


Завершение цикла while

Из книги автора

Завершение цикла while      Мы подошли к самому существенному моменту рассмотрения циклов while. При построении цикла while вы должны включить в него какие-то конструкции, изменяющие величину проверяемого выражения так, чтобы в конце концов оно стало ложным. В противном случае


Завершение ввода

Из книги автора

Завершение ввода      Как программа "узнает", сколько ей нужно считать чисел? В гл. 8 мы обсудили несколько решений этой проблемы, большинство из которых были неудовлетворительны. Однако теперь, когда есть функция getint( ), у нас нет проблем. Вот один подход:читаем число до тех


В завершение

Из книги автора

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


Завершение соединения TCP

Из книги автора

Завершение соединения TCP В то время как для установления соединения необходимо три сегмента, для его завершения требуется четыре сегмента.1. Одно из приложений первым вызывает функцию close, и мы в этом случае говорим, что конечная точка TCP выполняет активное закрытие (active


Завершение ассоциации

Из книги автора

Завершение ассоциации В отличие от TCP, SCRIPT не имеет состояния, соответствующего частично закрытой ассоциации. Когда один узел закрывает ассоциацию, второй узел должен перестать отправлять новые данные. Получатель запроса на закрытие ассоциации отправляет те данные,