Message Loop 原理及应用

Message Loop是一种等待和分派消息的编程结构,常见于Windows、iOS等系统。它通常是一个单线程设计,处理UI消息、通知、I/O事件等。消息循环始于线程执行,结束于循环控制表达式改变或线程被终止。嵌套消息循环用于处理任务,如模态对话框。线程间通信通过向对方消息队列投递消息实现,可加入空闲任务和递延任务等机制增强功能。
摘要由CSDN通过智能技术生成


此文已由作者王荣涛授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。


Message loop,即消息循环,在不同系统或者机制下叫法也不尽相同,有被叫做event loop,也有被叫做run loop或者其他名字的,它是一种等待和分派消息的编程结构,是经典的消息驱动机制的基础。为了方便起见,本文对各系统下类似的结构统称为message loop。

结构

Message loop,顾名思义,首先它是一种循环,这和我们初学C语言时接触的for、while是同一种结构。

在Windows下它可能是这个样子的:

MSG msg;BOOL bRet;
...while (bRet = ::GetMessage(&msg, NULL, 0, 0)) {    if (bRet == -1) {        // Handle Error
    } else {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}

在iOS下它可能是这个样子的:

BOOL shouldQuit = NO;
...BOOL ok = YES;
NSRunLoop *loop = [NSRunLoop currentRunLoop];while (ok && !shouldQuit) {
    ok = [loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}

而用libuv实现的I/O消息循环则可能是这样:

bool should_quit = false;
...
uv_loop_t *loop = ...while (!should_quit) {
    uv_run(loop, UV_RUN_ONCE);
}

在其他系统或机制下,它还有各自独特的实现,但都大体相似。

事实上,正常运行过程中在接到特殊消息或者指令之前,它就是一个彻底的死循环!同时,这样的结构也决定了它更多意义上是一种单线程上的设计。也正因为如此,对这种编程结构进行了封装的系统(比如iOS)也往往不保证或者根本不屑于提及其线程安全性。而多线程共享的消息循环在笔者看来在绝大部分场景下都属于逆天的设计,本文只讨论单线程上的消息循环。

Loop前面有个定语message,进一步表明它要处理的对象,即消息。这里说的消息是广义上的消息,它可能是UI消息、通知、I/O事件等等。那么消息从哪里来?消息循环又从哪里提取它们?这在不同系统或机制下有所不同:有来自消息队列的,有来自输入源/定时器源的,有来自异步网络、文件完成操作通知的,还有来自可观察对象状态变化的等等。这里把消息循环提取消息的源统称为消息源,简称源。

消息产生后源不会也无法主动推给消息循环。以Windows消息为例,一条异步窗口消息产生后它会被存放在窗口所属线程的消息队列上,如果消息循环不采取任何措施,那么它将永远无法被处理。消息循环从消息队列中去抽取,它才能被取出并分派。这种从消息队列中抽取

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值