Вход/Регистрация
Системное программирование в среде Windows
вернуться

Харт Джонсон М.

Шрифт:

Cancelled = TRUE;

continue;

}

WaitForSingleObject(q->q_guard, INFINITE);

 }

 /* Поместить сообщение в очередь. */

 if (!Cancelled) {

q_remove(q, msg, msize);

/* Сигнализировать о том, что очередь не заполнена, поскольку мы удалили сообщение. */

PulseEvent(q->q_nf);

ReleaseMutex(q->q_guard);

 }

 return Cancelled ? WAIT_TIMEOUT : 0;

}

В качестве функции АРС могут выступать и функция ShutDownReceiver, и функция ShutDownTransmitter, поскольку приемник и передатчик используют как функцию q_get, так и функцию q_put. Если требуется, чтобы функциям завершения было известно, из какого потока они выполняются, применяйте различные значения для аргументов функций АРС, которые передаются третьим аргументом функции QueueUserAPC во фрагменте кода, предшествующем программе 10.6.

Чтобы обеспечить согласованность с предыдущими версиями программы, в качестве кода завершения следует использовать значение WAIT_TIMEOUT.

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

Безопасная отмена выполнения потоков

Обсуждение предыдущего примера продемонстрировало, как безопасно отменить выполнение целевого потока, который использует состояния дежурного ожидания. Несмотря на использование АРС, такую отмену выполнения иногда называют синхронной отменой (synchronous cancellation), поскольку отмена выполнения, которую инициировал вызов функции QueueUserAPC главным потоком, сможет осуществиться лишь тогда, когда целевой поток достигнет безопасного состояния дежурного ожидания.

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

Асинхронная отмена выполнения потоков (asynchronous thread cancellation) может применяться в тех случаях, когда сигнал должен посылаться потоку, который выполняет интенсивные вычисления и находится в состоянии ожидания ввода/вывода или событий исключительно редко, если это вообще происходит. Возможность асинхронной отмены выполнения потоков в Windows отсутствует, хотя и существуют методики, использующие зависящий от типа процессора код, которые позволяют прерывать выполнение определенного потока.

Создание переносимых приложений с использованием потоков Pthreads

Потоки Pthreads уже неоднократно упоминались нами в качестве альтернативной модели многопоточного программирования и синхронизации, доступной в UNIX, Linux и других системах, не принадлежащих семейству Windows. Существует библиотека Windows Pthreads с открытым исходным кодом, используя которую можно создавать переносимые многопоточные приложения, способные выполняться на самых различных системах. Более подробное обсуждение этого вопроса вы найдете на Web-сайте книги. Указанная библиотека с открытым исходным кодом применяется в проекте ThreeStagePthreads, в котором также предоставляется соответствующая ссылка на сайт загрузки. 

Стеки потоков и допустимые количества потоков

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

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

  • Читать дальше
  • 1
  • ...
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: