среда, 21 апреля 2010 г.

Ожидание всех описателей в MsgWaitForMultipleObjects - это баг

Это перевод Waiting for all handles with MsgWaitForMultipleObjects is a bug waiting to happen. Автор: Реймонд Чен.

Функции MsgWaitForMultipleObjects и MsgWaitForMultipleObjectsEx позволяют вам указать, хотите ли вы ждать любого описателя или же все описатели (либо указанием bWaitAll = True, либо dwFlags = MWMO_WAITALL, соответственно). Но вы никогда не захотите ждать все описатели.

Ожидание всех описателей означает, что вызов функции не вернёт управление, пока все описатели не перейдут в сигнальное состояние и не придёт оконное сообщение, соответствующее вашим критериям. Поскольку обычно вы ждёте сообщений отдельно от логики событий (например, чтобы UI-поток был отзывчивым), а не как просто ещё одно событие для ожидания, то даже если все описатели перейдут в сигнальное состояние, ваша программа всё ещё будет стоять, пока не придёт оконное сообщение (а если вы думали, что вы будете приветливы к UI, когда используете MsgWaitForMultipleObjectsEx, то вы, на самом деле, ничего не исправили, потому что если первым придёт сообщение, то оно не будет обработано, пока не сработают все описатели). Функции, построенные поверх функции MsgWaitForMultipleObjectsEx, такие как MsgWaitForMultipleObjects и CoWaitForMultipleHandles, имеют аналогичное поведение.

Причину этого можно почерпнуть из документации MsgWaitForMultipleObjectsEx; вы просто должны надеть кепку "подумать". Заметьте, что если приходит сообщение, когда вы ждете любой описатель, то возвращается WAIT_OBJECT_0 + cHandles. Также заметьте, что максимальное число объектов, которые можно ожидать - это MAXIMUM_WAIT_OBJECTS - 1. Очевидно, что происходит за кулисами: функция MsgWaitForMultipleObjectsEx создает описатель, который переходит в сигнальное состояние, когда очередь сообщений достигает одного из состояний, которые вы запросили в маске. MsgWaitForMultipleObjectsEx добавляет этот описатель в конец вашего массива описателей, а затем просто вызывает WaitForMultipleObjectsEx (замечу, что получение доступа к этому внутреннему описателю не будет полезно вам, приложению, так как вы не знаете, как сказать оконному менеджеру, какие состояния должны приводить к установке события).

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.