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

33 }

Мы объявляем взаимное исключение с именем counter_mutex. Это исключение должно быть заблокировано потоком на то время, когда он манипулирует переменной counter. Когда мы запускали эту программу, результат всегда был правильным: значение переменной увеличивалось монотонно, а ее окончательное значение всегда оказывалось равным 10 000.

Насколько серьезной является дополнительная нагрузка, связанная с использованием взаимных исключений? Мы изменили программы, приведенные в листингах 26.11 и 26.12, заменив значение NLOOPна 50 000 (вместо исходного значения 5000), и засекли время, направив вывод на устройство /dev/null. Время работы центрального процессора в случае корректной версии, использующей взаимное исключение, увеличилось относительно времени работы некорректной версии без взаимного исключения на 10 %. Это означает, что использование взаимного исключения не связано со значительными издержками.

26.8. Условные переменные

Взаимное исключение позволяет предотвратить одновременный доступ к совместно используемой (разделяемой) переменной, но для того чтобы перевести поток в состояние ожидания (спящее состояние) до момента выполнения некоторого условия, необходим другой механизм. Продемонстрируем сказанное на следующем примере. Вернемся к нашему веб-клиенту из раздела 26.6 и заменим функцию Solaris thr_joinна pthread_join. Но мы не можем вызвать функцию pthread_joinдо тех пор, пока не будем знать, что выполнение потока завершилось. Сначала мы объявляем глобальную переменную, которая служит счетчиком количества завершившихся потоков, и организуем управление доступом к ней с помощью взаимного исключения.

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 maxnconn nlefttoconn 0) {

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

  ...

 }

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

 Pthread_mutex_lock(ndone_mutex);

 if (ndone 0) {

  for (i =0; i nfiles; 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 pthread.h


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;

Перейти на страницу:

Похожие книги

1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

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

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT
Access 2002: Самоучитель
Access 2002: Самоучитель

В книге рассматривается широкий круг вопросов, связанных с использованием программной среды Access 2002, которая является составной частью пакета Office 2002 и предназначена для создания банка данных в самых различных предметных областях.Подробно описывается методика проектирования объектов базы данных (таблицы, формы, отчеты, страницы доступа к данным, запросы, модули).Детально обсуждаются вопросы создания интегрированной базы данных в единой среде Access 2002: формирование БД с нуля, конвертирование в программную среду баз данных, созданных в ином программном окружении – Clarion, FoxPro.Особое внимание уделяется формированию разнообразных запросов к интегрированной базе данных Access 2002 с использованием языков программирования SQL, VBA и макросов.Приводятся общие сведения о возможностях языка обмена данными между различными компьютерами и приложениями (XML). Описываются возможности использования гиперссылок, связывающих базу данных с другими программными продуктами. Объясняется, как можно работать с базой данных Access 2002 без установки ее на компьютер, используя технологию ODBC (Open Data Base Connectivity). В приложениях приводятся количественные параметры Access 2002 и связанная с этой СУБД терминология.Предлагаемая книга будет полезна специалистам, занимающимся практической разработкой банков данных и приложений на их основе, а также студентам вузов, изучающим информатику.

Павел Юрьевич Дубнов

Программирование, программы, базы данных / ОС и Сети / Книги по IT