1 и 2 легко, просто используйте порт завершения ввода / вывода.
Но, как вы обнаружили, 3 требует (до Windows V6 1 ) один и тот же поток.
Если используется Windows> = V6, GetQueuedCompletionStatusEx
включает изменяемую опцию, которая заставит его вернуться, если в потоке выполняется APC. Поэтому используйте QueueUserAPC
, чтобы поставить в очередь неработающий APC 1 , когда вам нужен этот конкретный поток для выполнения какой-либо другой работы. Вам, конечно, понадобится некоторая потокобезопасная очередь, чтобы предоставить прерванному потоку инструкции о том, что отменить.
Если требуется совместимость с более ранними версиями, то все становится сложнее. Возможности:
Используйте параметр времени ожидания GetQueuedCompletionStatus
] (http://msdn.microsoft.com/library/aa364986), чтобы регулярно возвращаться для проверки отмены.
Или, возможно, более практично, разделить пул потоков на две группы. Потоки, которые инициируют и отменяют IO. Все остальное время эти потоки тратят на ожидание сигнала о выполнении одного из этих действий. Другая часть пула ожидает завершения ввода-вывода с GetQueuedCompletionStatus
.
Ничто из этого не так приятно, но это всегда проблема старых версий: им не хватает функциональности.
1 Используйте неработающий APC вместо выполнения работы в APC, чтобы обойти ограничения на то, что можно сделать в APC, и его неотъемлемые проблемы с параллелизмом. (Поскольку APC выполняется в потоке, все блокировки, удерживаемые потоком, сохраняются в APC, любое защищенное состояние будет произвольно несовместимым.)