Threading 101: Что такое диспетчер? - PullRequest
5 голосов
/ 09 февраля 2010

Давным-давно я вспомнил этот материал наизусть. Со временем мое понимание ослабло, и я собираюсь обновить его.

Насколько я помню, любое так называемое однопоточное приложение имеет два потока:

a) основной поток, который имеет указатель на основную точку входа или точки входа DllMain; и

b) Для приложений, имеющих некоторый пользовательский интерфейс, поток пользовательского интерфейса, a.k.a вторичный поток, в котором работает WndProc, т. Е. Поток, который выполняет WndProc, который получает сообщения, которые Windows отправляет ему. Короче говоря, поток, который выполняет цикл сообщений Windows.

Для приложений пользовательского интерфейса основной поток находится в состоянии блокировки, ожидая сообщений из Windows. Когда он получает их, он ставит их в очередь и отправляет их в цикл обработки сообщений (WndProc), и поток пользовательского интерфейса запускается.

Насколько я понимаю, основной поток, который находится в состоянии блокировки, это:

C ++

while(getmessage(/* args &msg, etc. */))
{
    translatemessage(&msg, 0, 0);
    dispatchmessage(&msg, 0, 0);
}

Приложения C # или VB.NET WinForms:

Application.Run( new System.Windows.Forms() );

Это то, что они называют Диспетчером?

Мои вопросы:

а) Правильно ли мое понимание выше?

б) Что, во имя ада, является Диспетчером?

в) Укажите мне ресурс, где я могу лучше понять потоки с точки зрения Windows / Win32, а затем связать его с языками высокого уровня, такими как C #. Петцольд щедро обсуждает эту тему в своей эпической работе.

Хотя я полагаю, что я в некоторой степени прав, подтверждение будет облегчением.

1 Ответ

1 голос
/ 09 февраля 2010

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

Обычно диспетчер принимает некоторые события и, основываясь на их содержимом или типе, отправляет (отправляет, если хотите) их другому фрагменту кода (часто в другом потоке, но не всегда). В этом смысле сам поток обработчика событий является простым диспетчером. На другом конце очереди платформа обычно предоставляет другого диспетчера, который будет извлекать события из очереди. Например, отправка событий мыши слушателям мыши, события клавиатуры слушателям клавиатуры и т. Д.

Edit:

Простой диспетчер может выглядеть так:

class Event{
   public:
   EventType type; //Probably an enum
   String data; //Event data
};

class Dispatcher{
   public:
   ...

   dispatch(Event event)
   {
      switch(event.type)
      {
         case FooEvent:
            foo(event.data);
            break;
            ...
       }
   };

Большинство людей, с которыми я встречался, используют «диспетчер», чтобы описать нечто большее, чем просто прохождение. В этом случае он выполняет различные действия на основе переменной типа, что согласуется с большинством диспетчеров, которые я видел. Часто переключатель заменяется полиморфизмом, но переключатель проясняет, что происходит для примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...