Очередизация асинхронных вызовов процедур

Очередизация асинхронных вызовов процедур

Один поток (главный) помещает АРС в очередь целевого потока с помощью функции QueueUserAPC: 

DWORD QueueUserAPC(PAPCFUNC pfnAPC, HANDLE hThread, DWORD dwData)

hThread — дескриптор целевого потока. dwData — аргумент, который будет передан функции АРС при ее выполнении и может являться кодом завершения или сообщать функции иную информацию.

В основной функции программы ThreeStageCancel.с (сравните с программой 10.5) вызовы TerminateThread заменяются вызовами QueueUserAPC следующим образом:

// TerminateThread(transmitter_th, 0) ; заменить на АРС

// TerminateThread(receiver_th, 0); заменить на АРС

tstatus = QueueUserAPC(ShutDownTransmitter, transmitter_th, 1);

if (tstatus == 0) ReportError(…);

tstatus = QueueUserAPC(ShutDownReceiver, receiver_th, 2);

if (tstatus == 0) ReportError (…);

Функция QueueUserAPC в случае успешного ее завершения возвращает ненулевое значение, иначе — нуль. В то же время, функция GetLastError () не возвращает никакого полезного значения, и поэтому при вызове функции ReportError не требуется задавать текст сообщения об ошибке (значением последнего аргумента является FALSE).

pfnAPC — указатель на фактическую функцию, вызываемую целевым потоком, как показывает следующий фрагмент, взятый из программы ThreeStageCancel. с:

/* АРС для завершения выполнения потребителя. */

void WINAPI ShutDownReceiver(DWORD n) {

 printf("Внутри ShutDownReceiver. %d ", n);

 /* Освободить все ресурсы (в данном примере отсутствуют). */

 return;

}

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

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

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

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

Кэширование ресурсоемких вызовов

Из книги Разгони свой сайт автора Мациевский Николай

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


Кэшируем цепочки вызовов

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

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


Реализация групповых вызовов

Из книги Основы объектно-ориентированного программирования автора Мейер Бертран

Реализация групповых вызовов Напомним, что делегаты .NET наделены возможностью группового вызова. Другими словами, объект делегата может поддерживать не один метод, а целый список доступных для вызова методов. Когда требуется добавить в объект делегата несколько методов,


Оптимизация вызовов

Из книги Windows Script Host для Windows 2000/XP автора Попов Андрей Владимирович

Оптимизация вызовов На уровнях 2 и 3 неизбежно использование явных вызовов процедуры подобных my_polygon.set_size (5) для изменения значения атрибута. Существует опасение, что использование такого стиля на уровне 4 негативно скажется на производительности. Тем не менее компилятор


Цепочка вызовов

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

Цепочка вызовов Обсуждая механизм обработки исключений, полезно иметь ясную картину последовательности вызовов, приведших в итоге к исключению. Это понятие уже появлялось при рассмотрении механизма языка Ada. Рис. 12.1.  Цепочка вызововПусть r0 будет корневой процедурой


Просмотр стека вызовов 

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

Просмотр стека вызовов  В отладчике можно вывести окно Call Stack со списком всех активных процедур и функций сценария. Для этого нужно выполнить команду View|Call Stack. Например, если вызвать это окно, находясь внутри функции MyFunc() в сценарии ForDebug.js, то в списке мы увидим название


16.6. Семантика вызовов

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

16.6. Семантика вызовов В листинге 15.24 мы привели пример клиента интерфейса дверей, повторно отсылавшего запрос на сервер при прерывании вызова door_call перехватываемым сигналом. Затем мы показали, что при этом процедура сервера вызывается дважды, а не однократно. Потом мы


Отличия процедур типа Function от процедур типа Sub

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

Отличия процедур типа Function от процедур типа Sub Между процедурами типа Function и типа Sub есть одно существенное отличие: в процедуре типа Function обязательно где-то должен присутствовать по крайней мере один оператор, задающий значение этой функции. При этом используется имя


22.4. Трассировка системных вызовов

Из книги iOS. Приемы программирования автора Нахавандипур Вандад

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


2.2.2. Ошибки системных вызовов

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

2.2.2. Ошибки системных вызовов Большинство из нас училось писать программы, которые выполняются по четко намеченному алгоритму. Мы разделяли программу на задачи и подзадачи, и каждая функция решала свою задачу, вызывая другие функции для решения соответствующих подзадач.


В.1. Трассировка системных вызовов

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

В.1. Трассировка системных вызовов Многие версии Unix предоставляют возможность трассировки (отслеживания) системных вызовов. Зачастую это может оказаться полезным методом отладки.Работая на этом уровне, необходимо различать системный вызов и функцию. Системный вызов


Производительность системных вызовов

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

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


Обработка системных вызовов

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

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