Threading 101: Что такое диспетчер?
Однажды я вспомнил этот материал наизусть. Со временем мое понимание ослабло, и я хочу его освежить.
Насколько я помню, любое так называемое однопоточное приложение имеет два потока:
а) основной поток, имеющий указатель на основную точку входа или точки входа DllMain; а также
b) Для приложений, имеющих некоторый пользовательский интерфейс, поток пользовательского интерфейса, то есть вторичный поток, в котором работает 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() );
Это то, что они называют Диспетчером?
Мои вопросы:
а) Правильно ли мое понимание выше?
б) Что, во имя ада, Диспетчер?
c) Укажите мне ресурс, где я могу лучше понять потоки с точки зрения Windows/Win32, а затем связать его с языками высокого уровня, такими как C#. Петцольд щедро обсуждает эту тему в своей эпической работе.
Хотя я полагаю, что я в чем-то прав, подтверждение будет облегчением.
1 ответ
Это зависит от того, что вы считаете основным потоком. В большинстве сред пользовательского интерфейса имеется поток обработчика событий, который в основном находится в режиме ожидания, ожидая событий низкого уровня. Когда происходит событие, этот поток получает блокировку в очереди событий и добавляет туда события. Это вряд ли то, что я считаю основным потоком.
Обычно диспетчер принимает некоторые события и, основываясь на их содержимом или типе, отправляет (отправляет, если хотите) их другому фрагменту кода (часто в другом потоке, но не всегда). В этом смысле сам поток обработчика событий является простым диспетчером. На другом конце очереди платформа обычно предоставляет другого диспетчера, который будет извлекать события из очереди. Например, отправка событий мыши слушателям мыши, события клавиатуры слушателям клавиатуры и т. Д.
Редактировать:
Простой диспетчер может выглядеть так:
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;
...
}
};
Большинство людей, с которыми я встречался, используют "диспетчер", чтобы описать нечто большее, чем просто прохождение. В этом случае он выполняет различные действия в зависимости от переменной типа, что согласуется с большинством диспетчеров, которые я видел. Часто переключатель заменяется полиморфизмом, но переключатель проясняет, что происходит для примера.