message loop
- 线程的事件处理循环
- 每个thread至少有一个message loop
- message loop主要处理task,依靠不同类型的message pump也可以处理其他任务,如 UI消息等
- message loop 继承MessagePump::Delegate 实现委托接口
- message loop 有可重入保护,一个任务未执行完,其他任务不可以开始
- 只有当创建嵌入message pump时,才可发生可重入,如创建模态对话框,OLE函数(拖拽),打印等。
- destruction_observers message loop 销毁时,通知此列表的对象。list结构,观察者模式
- PostTask() 多线程调用,使task在messageloop所属线程的run()中被处理
- DeleteSoon() ReleaseSoon() 保持变量,使之一直在消息循环中有效
- 运行相关函数被重新封装至RunLoop类中
- taskobservers task被处理之前和之后通知 观察者模式
- type_ 类型 与 message pump相关
- nestabletasksallowed_ 可重入标识
- 两个队列 workqueue(需要被处理的task的队列), delayedworkqueue(按时间排序),
- IncomingTaskQueue智能指针 IncomingTaskQueue批量复制到workqueue或delayedwork_queue中起到减少锁等待的作用
- MessageLoopForUI/MessageLoopForIO 提供为pump加入(删除)观察者的接口
- lazytlsptr 静态对象保持message loop指针
message loop proxy
- 多线程访问message loop对象,使用proxy管理message loop生命周期
- 返回带引用计数的message loop的智能指针
- 相关文件 messageloopproxy.cc(h) messageloopimpl.cc(h)
message pump
- 消息泵,派发task,处理非task任务
- mesage loop的pump_指向message pump
- loop按类型包含一个同类型的pump
- 用来负责处理task以外的消息,决定task处理的时机,委托给loop处理task 委托模式
- pump 的 run loop过程
- DoInernalWork() 处理非task任务,如UI消息,完成端口消息
- WaitForWork() 阻塞等待任务
- 循环调用DoInternalWork(), DoWork(), DoDelayedWork()保证所有队列任务都可被执行
- 每次循环检查退出标志
for (;;) { bool did_work = DoInternalWork(); if (should_quit_) break; did_work |= delegate_->DoWork(); if (should_quit_) break; TimeTicks next_time; did_work |= delegate_->DoDelayedWork(&next_time); if (should_quit_) break; if (did_work) continue; did_work = delegate_->DoIdleWork(); if (should_quit_) break; if (did_work) continue; WaitForWork(); }
- message loop default
- evnet唤醒loop
- delayedworktime 定时处理delayed work
- message pump ozone:This class implements a message-pump for processing events from input devices Refer to MessagePump for further documentation.
- message pump dispatcher:嵌套message loop 的消息派发相关
- messagepumpobserver.h x11相关
windows 下 message pump的实现
MessagePumpWin | interit | +---------------+ | | MessagePumpForUI MessagePumpForUI
- MessagePumpWin
- 观察者列表 在处理消息的前后分别通知观察者,观察者模式
- 延时任务运行时间
- RunState 消息运行,包括消息重入的处理
- MessagePumpForUI
- 实现为一个传统的本地windows message pump
- kMsgHaveWork是一个特殊消息作为一个event去唤醒sub pump处理task
- 避免kMsgHaveWork被重复放入消息队列 检查havework变量保证
- sub pump无task时自动挂起,有task时被自动唤醒
- WMPAINT和WMTIMER优先级总是高于其他投递的消息(如,kMsgHaveWork)
- DoRunLoop() 消息泵,相当于
while(GetMessage(&Msg,NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); }
- WndProcThunk() 消息处理函数
- MessagePumpForIO
- 完成端口
- 观察者列表 在处理消息的前后分别通知观察者。观察者模式
run loop
- 消息循环
- 从message loop剥离,在栈上分配对象,速度更快;降低message loop的复杂度
- _loop为message loop对象的指针
- previousrunloop_ 上一个run loop的指针
- BeforeRun()中push Runloop stack
- AfterRun()中pop Runloop stack
- 每次run前都发一个quit task目的是如果之前有message loop则退出。
线程内消息
线程内部是如何进行的。但你需要进行费时的操作时候,可以派发一个事件和回调函数给 自身线程的MessageLoop,然后MessageLoop会调度该回调函数以执行其操作。问题是这有必要 吗?直接调用不就可以吗?答案是不可以,或者说是最好不要这么做,其原因在于,如果当前的 MessageLoop里面有优先级更高的事件和任务需要处理时,你这样做会阻碍它们的执行。
参考
理解WebKit和Chromium: 消息循环(Message Loop) Chrome学习笔记(一):线程模型,消息循环 理解WebKit和Chromium_ Chromium的多线程机制
标签:
chromium
日期: 2014-08-29 17:30:06, 10 years and 140 days ago