多线程入门:什么是 Dispatcher?

5

从前,我曾经牢记这些内容。随着时间的推移,我的理解逐渐淡化,现在我想更新一下。

据我回忆,任何所谓的单线程应用程序都有两个线程:

a) 主线程,它指向主要或DllMain入口点的指针;和

b) 对于具有某些UI的应用程序,有一个UI线程,也称为次要线程,在该线程上运行WndProc,即执行接收Windows发布的消息的WndProc的线程。简而言之,执行Windows消息循环的线程。

对于UI应用程序,主线程处于阻塞状态,等待来自Windows的消息。当它们接收到消息时,它们将其排队并将其分派到消息循环(WndProc),然后启动UI线程。

据我理解,处于阻塞状态的主线程是这样的:

C++

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

C#或VB.NET WinForms应用程序:

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

这是他们所说的调度器吗?

我的问题是:

a)我上面的理解正确吗?

b)调度器到底是什么鬼?

c)请指引我一个资源,让我从Windows/Win32的角度更好地了解线程,然后将其与像C#这样的高级语言联系起来。Petzold在他的经典作品中对此话题的讨论很少。

尽管我认为我有一定的正确性,但确认一下会让人感到宽慰。

1个回答

1

这取决于您认为哪个是主线程。大多数UI框架都会有一个事件处理程序线程,它大部分时间处于空闲状态,等待低级别事件的发生。当事件发生时,此线程会锁定事件队列,并将事件添加到其中。虽然如此,但我不认为这是主线程。

通常情况下,调度程序会接收一些事件,并根据其内容或类型将它们发送(如果您愿意,可以称之为“调度”)到另一段代码中(通常在另一个线程中,但并非总是如此)。从队列的另一端,框架通常提供另一个调度程序,它将从队列中取出事件。例如,将鼠标事件发送给鼠标侦听器,将键盘事件发送给键盘侦听器等。

编辑:

一个简单的调度程序可能看起来像这样:

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;
            ...
       }
   };

我遇到的大多数人使用“dispatcher”来描述不仅是简单的传递。在这种情况下,它根据类型变量执行不同的操作,这与我看到的大多数调度程序一致。通常,开关会被多态性所取代,但开关使得事情更清楚明了。

谢谢,patros。你的解释使我对这个问题有了更清晰的理解。根据你的解释,调度器比上面的示例要更广泛一些。上面的示例(C++和C#代码片段)是调度器的实例。谢谢。然而,你的解释中有些文字让人感到困惑。听起来你对调度器的定义似乎只是一个事件发布者和事件消费者之间的中介。你能用一些代码来举例说明一下调度器吗? - Water Cooler v2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接