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

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

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

UNIX: разработка сетевых приложений - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

4. Другой поток, например поток с номером n, вызывает функцию readline, возможно, в тот момент, когда поток с номером 0 все еще находится в стадии выполнения функции readline.

Функция readlineвызывает функцию pthread_once, чтобы инициализировать ключ этого элемента собственных данных, но так как эта функция уже была однажды вызвана, то больше она не выполняется.

5. Функция readlineвызывает функцию pthread_getspecificдля получения значения указателя pkey[1]для данного потока, но возвращается пустой указатель. Тогда поток вызывает функцию mallocи функцию pthread_setspecific, как и в случае с потоком номер 0, инициализируя элемент собственных данных потока, соответствующий этому ключу (1). Этот процесс иллюстрирует рис. 26.5.

Рис 265 Структуры данных после того как поток n инициализировал свои - фото 128

Рис. 26.5. Структуры данных после того, как поток n инициализировал свои собственные данные

6. Поток номер n продолжает выполнять функцию readline, используя и модифицируя свои собственные данные.

Один вопрос, который мы пока не рассмотрели, заключается в следующем: что происходит, когда поток завершает свое выполнение? Если поток вызвал функцию readline, эта функция выделила в памяти область, которая должна быть освобождена по завершении выполнения потока. Для этого используется указатель-деструктор , показанный на рис. 26.2. Когда поток, создающий элемент собственных данных, вызывает функцию pthread_key_create, одним из аргументов этой функции является указатель на функцию-деструктор . Когда выполнение потока завершается, система перебирает массив pkeyдля данного потока, вызывая соответствующую функцию-деструктор для каждого непустого указателя pkey. Под «соответствующим деструктором» мы понимаем указатель на функцию, хранящийся в массиве Keyс рис. 26.2. Таким образом осуществляется освобождение памяти, занимаемой собственными данными потока, когда выполнение потока завершается.

Первые две функции, которые обычно вызываются при работе с собственными данными потока, — это pthread_onceи pthread_key_create.

#include

int pthread_once(pthread_once_t * onceptr , void (* init )(void));

int pthread_key_create(pthread_key_t * keyptr , void (* destructor )(void * value ));

Обе функции возвращают: 0 в случае успешного выполнения, положительное значение Exxx в случае ошибки

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

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

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

pthread_key_t rl_key;

pthread_once_t rl_once = PTHREAD_ONCE_INIT;

void readline_destructor(void *ptr) {

free(ptr);

}

void readline_once(void) {

pthread_key_create(&rl_key, readline_destructor);

}

ssize_t readline(...) {

...

pthread_once(&rl_once, readline_once);

if ((ptr = pthread_getspecific(rl_key)) == NULL) {

ptr = Malloc(...);

pthread_setspecifiс(rl_key, ptr);

/* инициализация области памяти, на которую указывает ptr */

}

...

/* используются значения, на которые указывает ptr */

}

Каждый раз, когда вызывается функция readline, она вызывает функцию pthread_once. Эта функция использует значение, на которое указывает ее аргумент-указатель onceptr(содержащийся в переменной rl_once), чтобы удостовериться, что функция initвызывается только один раз. Функция инициализации readline_onceсоздает ключ для собственных данных потока, который хранится в rl_keyи который функция readlineзатем использует в вызовах функций pthread_getspecificи pthread_setspecific.

Функции pthread_getspecificи pthread_setspecificиспользуются для того, чтобы получать и задавать значение, ассоциированное с данным ключом. Это значение представляет собой тот указатель, который показан на рис. 26.3. На что указывает этот указатель — зависит от приложения, но обычно он указывает на динамически выделяемый участок памяти.

#include

void *pthread_getspecific(pthread_key_t key );

Возвращает: указатель на собственные данные потока (возможно, пустой указатель)

int pthread_setspecific(pthread_key_t key , const void * value );

Возвращает: 0 в случае успешного выполнения, положительное значение Exxx в случае ошибки

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

Пример: функция readline, использующая собственные данные потока

В этом разделе мы приводим полный пример использования собственных данных потока, преобразуя оптимизированную версию функции readlineиз листинга 3.12 к виду, безопасному в многопоточной среде, не изменяя последовательность вызовов.

В листинге 26.5 показана первая часть функции: переменные pthread_key_tи pthread_once_t, функции readline_destructorи readline_onceи наша структура Rline, которая содержит всю информацию, нужную нам для каждого потока.

Листинг 26.5. Первая часть функции readline, безопасной в многопоточной среде

//threads/readline.c

1 #include "unpthread.h"

2 static pthread_key_t rl_key;

3 static pthread_once_t rl_once = PTHREAD_ONCE_INIT;

4 static void

5 readline_destructor(void *ptr)

6 {

7 free(ptr);

8 }

9 static void

10 readline_once(void)

11 {

12 Pthread_key_create(&rl_key, readline_destructor);

13 }

14 typedef struct {

15 int rl_cnt; /* инициализируется нулем */

16 char *rl_bufptr; /* инициализируется значением rl_buf */

17 char rl_buf[MAXLINE];

18 } Rline;

Деструктор

4-8 Наша функция-деструктор просто освобождает всю память, которая была выделена для данного потока.

«Одноразовая» функция

9-13 Мы увидим, что наша «одноразовая» (то есть вызываемая только один раз) функция вызывается однократно из функции pthread_onceи создает ключ, который затем используется в функции readline.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




UNIX: разработка сетевых приложений отзывы


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


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x