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

Интервал:

Закладка:

Сделать

int ndone; /* количество потоков, завершивших выполнение */

pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;

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

void* do_get_read(void *vptr) {

...

Pthread_mutex_lock(&ndone_mutex);

ndone++;

Pthread_mutex_unlock(&ndone_mutex);

return(fptr); /* завершение выполнения потока */

}

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

while (nlefttoread > 0) {

while (nconn 0) {

/* находим файл для чтения */

...

}

/* Проверяем, не завершен ли поток */

Pthread_mutex_lock(&ndone_mutex);

if (ndone > 0) {

for (i =0; i

if (file[i].f_flags & F_DONE) {

Pthread_join(file[i].f_tid, (void**)&fptr);

/* обновляем file[i] для завершенного потока */

...

}

}

}

Pthread_mutex_unlock(&ndone_mutex);

}

Это означает, что главный поток никогда не переходит в спящее состояние, а просто входит в цикл, проверяя каждый раз значение переменной ndone. Этот процесс называется опросом ( polling ) и рассматривается как пустая трата времени центрального процессора.

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

В терминах Pthreads условная переменная — это переменная типа pthread_cond_t. Такие переменные используются в следующих двух функциях:

#include

int pthread_cond_wait(pthread_cond_t * cptr , pthread_mutex_t * mptr );

int pthread_cond_signal(pthread_cond_t * cptr );

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

Слово signalв названии второй функции не имеет отношения к сигналам Unix SIGxxx.

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

int ndone;

pthread_mutex_t ndone_mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t ndone_cond = PTHREAD_COND_INITIALIZER;

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

Pthread_mutex_lock(&ndone_mutex);

ndone++;

Pthread_cond_signal(&ndone_cond);

Pthread_mutex_unlock(&ndone_mutex);

Затем основной цикл блокируется в вызове функции pthread_cond_wait, ожидая оповещения о завершении выполнения потока:

while (nlefttoread > 0) {

while (nconn 0) {

/* находим файл для чтения */

...

}

/* Ждем завершения выполнения какого-либо потока */

Pthread_mutex_lock(&ndone_mutex);

while (ndone == 0)

Pthread_cond_wait(&ndone_cond, &ndone_mutex);

for (i = 0; i

if (file[i].f_flags & F_DONE) {

Pthread_join(file[i].f_tid, (void**)&fptr);

/* обновляем file[i] для завершенного потока */

...

}

}

Pthread_mutex_unlock(&ndone_mutex);

}

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

Почему взаимное исключение всегда связано с условной переменной? «Условие» обычно представляет собой значение некоторой переменной, используемой совместно несколькими потоками. Взаимное исключение требуется для того, чтобы различные потоки могли задавать и проверять значение условной переменной. Например, если в примере кода, приведенном ранее, отсутствовало бы взаимное исключение, то проверка в главном цикле выглядела бы следующим образом:

/* Ждем завершения выполнения одного или нескольких потоков */

while (ndone == 0)

Pthread_cond_wait(&ndone_cond, &ndone_mutex);

Но при этом существует вероятность, что последний поток увеличивает значение переменной ndoneпосле проверки главным потоком условия ndone == 0, но перед вызовом функции pthread_cond_wait. Если это происходит, то последний «сигнал» теряется, и основной цикл оказывается заблокированным навсегда, так как он будет ждать события, которое никогда не произойдет.

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

/* Ждем завершения выполнения одного или нескольких потоков */

Pthread_mutex_lock(&ndone_mutex);

while (ndone == 0) {

Pthread_mutex_unlock(&ndone_mutex);

Pthread_cond_wait(&ndone_cond, &ndone_mutex);

Pthread_mutex_lock(&ndone_mutex);

}

Существует вероятность того, что по завершении выполнения поток увеличит на единицу значение переменной ndoneи это произойдет между вызовом функций pthread_mutex_unlockи pthread_cond_wait.

Обычно функция pthread_cond_signalвыводит из состояния ожидания один поток, на который указывает условная переменная. Существуют ситуации, когда некоторый поток знает, что из состояния ожидания должны быть выведены несколько потоков. В таком случае используется функция pthread_cond_broadcast, выводящая из состояния ожидания все потоки, которые блокированы условной переменной.

#include

int pthread_cond_broadcast(pthread_cond_t * cptr );

int pthread_cond_timedwait(pthread_cond_t * cptr , pthread_mutex_t * mptr ,

const struct timespec * abstime );

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

Функция pthread_cond_timedwaitпозволяет потоку задать предельное время блокирования. Аргумент abstimeпредставляет собой структуру timespec(определенную в разделе 6.9 при рассмотрении функции pselect), которая задает системное время для момента, когда функция должна возвратить управление, даже если к этому моменту условная переменная не подала сигнал. Если возникает такая ситуация, возвращается ошибка ETIME.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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