Очередизация асинхронных вызовов процедур
Очередизация асинхронных вызовов процедур
Один поток (главный) помещает АРС в очередь целевого потока с помощью функции 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 аналогична вышеприведенной, отличаясь от нее только текстом сообщения. Сразу трудно понять, каким образом эта функция, которая, казалось бы, не выполняет никаких существенных операций, может инициировать прекращение выполнения целевого принимающего потока. Соответствующие пояснения приводятся далее в этой главе.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Производительность системных вызовов
Производительность системных вызовов Системные вызовы в операционной системе Linux работают быстрее, чем во многих других операционных системах. Это отчасти связано с невероятно малым временем переключения контекста. Переход в режим ядра и выход из него являются хорошо
Обработка системных вызовов
Обработка системных вызовов Приложения пользователя не могут непосредственно выполнять код ядра. Они не могут просто вызвать функцию, которая существует в пространстве ядра, так как ядро находится в защищенной области памяти. Если программы смогут непосредственно
Кэширование ресурсоемких вызовов
Кэширование ресурсоемких вызовов Как показывает практика, лучше всего будет использовать переменные максимально близко к области их объявления и избегать использования глобальных переменных любой ценой. Глобальная область видимости обычно содержит десятки, если не
Кэшируем цепочки вызовов
Кэшируем цепочки вызовов Распознавание (разрешение) ссылки на объект или метод выполняется каждый раз, когда происходит обращение к этому объекту или методу. Переменные разрешаются всегда в обратном порядке: от более частной области видимости к более общей. Поэтому,
Просмотр стека вызовов
Просмотр стека вызовов В отладчике можно вывести окно Call Stack со списком всех активных процедур и функций сценария. Для этого нужно выполнить команду View|Call Stack. Например, если вызвать это окно, находясь внутри функции MyFunc() в сценарии ForDebug.js, то в списке мы увидим название
В.1. Трассировка системных вызовов
В.1. Трассировка системных вызовов Многие версии Unix предоставляют возможность трассировки (отслеживания) системных вызовов. Зачастую это может оказаться полезным методом отладки.Работая на этом уровне, необходимо различать системный вызов и функцию. Системный вызов
22.4. Трассировка системных вызовов
22.4. Трассировка системных вызовов Вы когда-нибудь задумывались о том, какие системные вызовы использует наша программа во время своего выполнения? Если да, то этот пункт как раз для вас. Возможно, пока он только удовлетворит ваше любопытство, но через некоторое время эта
16.6. Семантика вызовов
16.6. Семантика вызовов В листинге 15.24 мы привели пример клиента интерфейса дверей, повторно отсылавшего запрос на сервер при прерывании вызова door_call перехватываемым сигналом. Затем мы показали, что при этом процедура сервера вызывается дважды, а не однократно. Потом мы
Отличия процедур типа Function от процедур типа Sub
Отличия процедур типа Function от процедур типа Sub Между процедурами типа Function и типа Sub есть одно существенное отличие: в процедуре типа Function обязательно где-то должен присутствовать по крайней мере один оператор, задающий значение этой функции. При этом используется имя
Реализация групповых вызовов
Реализация групповых вызовов Напомним, что делегаты .NET наделены возможностью группового вызова. Другими словами, объект делегата может поддерживать не один метод, а целый список доступных для вызова методов. Когда требуется добавить в объект делегата несколько методов,
11.2. Обработка задержек при асинхронных соединениях
11.2. Обработка задержек при асинхронных соединениях Необходимо задать лимит ожидания — проще говоря, задержку — при асинхронном
2.2.2. Ошибки системных вызовов
2.2.2. Ошибки системных вызовов Большинство из нас училось писать программы, которые выполняются по четко намеченному алгоритму. Мы разделяли программу на задачи и подзадачи, и каждая функция решала свою задачу, вызывая другие функции для решения соответствующих подзадач.
Оптимизация вызовов
Оптимизация вызовов На уровнях 2 и 3 неизбежно использование явных вызовов процедуры подобных my_polygon.set_size (5) для изменения значения атрибута. Существует опасение, что использование такого стиля на уровне 4 негативно скажется на производительности. Тем не менее компилятор
Цепочка вызовов
Цепочка вызовов Обсуждая механизм обработки исключений, полезно иметь ясную картину последовательности вызовов, приведших в итоге к исключению. Это понятие уже появлялось при рассмотрении механизма языка Ada. Рис. 12.1. Цепочка вызововПусть r0 будет корневой процедурой