事件
简而言之就是发生了一件事情, 文件读完了, socket打开了, socket关闭了, 指的是一件发生了的事情.
消息
message, 我们可以认为就是简单的几个单词, 比如:张三告诉我文件读完了, 我获得了一个消息, 这个消息是张三告诉我的, 关于文件读完的消息.
事件驱动
监听一组或是多组事件, 一旦事件发生, 就巴拉巴拉巴拉...
libevent事件驱动
linux下多线程编程, 我们一般采用libevent事件驱动, 不断的监听多个事件, 实现多个worker的功能.
// 创建一个事件循环
event_base* m_ebase = event_base_new();
// 创建一个事件
event* m_event = event_new(m_ebase, fd, EV_READ | EV_PERSIST, cb, pThis);
// 开启循环
event_base_dispatch(m_ebase)
其中创建一个事件的时候, 我们给了一个fd, 需要监听的事件EV_READ | EV_PERSIST, 一个回调函数cb, pThis指的是回调的对象(参数). 当fd发生了我们监听的事件的时候, 就会回调到对应的函数. 通过添加多个fd, 我们可以为socket, 文件, 流等各种io添加监听函数, 不同事件的发生, 回调到不同的函数, 从而实现事件驱动.
消息驱动
windows的消息机制. 当鼠标点击,发生点击事件, windows检测到这一事件的发生, 随即发送一个消息到消息队列, 这个消息会附带一些数据, 地点啊, 坐标啊神马. windows线程在不断的轮询这个消息队列, 不断的获取消息, 获得这个消息之后做对应的处理, 从而实现消息驱动.
// 要保证自己消息队列已经创建了, 强制创建线程消息循环
MSG msg;
MSG msg;
while (true)
{
PeekMessage(&msg, NULL, WM_USER, WM_USER, NULL);
if (msg.message == WM_USER)
{
break;
}
else
{
PostMessage(NULL, WM_USER, NULL, NULL);
}
}
// 开始循环
BOOL bRes = FALSE;
MSG msg;
while((bRes = GetMessage( &msg, NULL, 0, 0 )) != 0)
{
if (bRes == -1)
{
break;
}
else
{
switch (msg.message)
{
case WM_QUIT:
{
ExitThread(0);
break;
}
default:
{
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
}
}
}
}
// 发送一个消息
::PostThreadMessage(m_ThreadID, WM_QUIT, NULL, NULL);
总结
个人认为事件驱动和消息驱动并没有本质的区别, windows为了降低耦合, 大量使用的消息驱动, 但是消息发生的本质还是事件的发生, 然后由事件转化为消息, 源头还是一致的.
欢迎大家订阅雀观代码, 我将给你讲述, 中小企业程序员, 淘金路上的故事.