These days I am interesting with event driven programming,so I search some materials from web. This is a basic model,it contains many events,and each event has its own event handler. When the handler thread fetch a new event from FIFO ( or message queue),it calls the event's registered event handler. In a GUI framework,each widget has its own event container and event loop. when it starts,the event loop starts too.When it detects a new event from event container,then translate it and handle it. But for a huge project,with many widgets,how does it know the event should be sent to which widget? or we can say,I generate a event,but there are many destinations. Which widget should I send this event to ? So,in general,in a GUI process,like Qt framework,it has a QApplication, all events from sub-widgets will be send to it. The QApplication has a event loop,and fetch events from message queue and dispach events to the current focused widget. Event generator................. postEvent to QApplication. Event translator..................QApplicaion's event loop fetch events and translate them. Event dispatcher..................After translate them,dispatch them to the destinations. Event handler.....................The final user,use this event to do its jobs. #define NOEVENT 0 typedef void *(*EventHandler)(void *); void *doNothing(void *p) { /*do nothing absolutely*/ return NULL; } typedef struct _event { EventHandler handler; }Event, *PEvent;
Event AllEvents[1000];
unsigned short counter = 0;
void InitEvents()
{
LOCK(AllEvents);
for(int i = 0; i < 1000; i++)
{
AllEvents[i].handler = doNothing;
}
UNLOCK(AllEvents);
}
void AddEvent(int EventType, EventHandler ev_handler)
{
LOCK(AllEvents);
AllEvents[EventType].handler = ev_handler;
UNLOCK(AllEvents);
}
void RemoveEvent(int EventType, EventHandler ev_handler)
{
LOCK(AllEvents);
AllEvents[EventType] = doNothing;
UNLOCK(AllEvents); /*to safeguard the event loop*/
}
/*to be run in separate thread*/
void EventLoop()
{
int event = NOEVENT;
EventHandler handler; //This is event loop,fetch a event,translate it,dispatch it.
while(1){
while(event == NOEVENT)event=GetEvents();
handler = AllEvents[event].handler; //call the event handlers.
handler();/*perform on an event*/
}
}
This is only a basic event driven programming model.
In the real-life,events handler is very complex.There are many events for examples:
QMouseEvent,QMouseMoveEvent,QMouseHoverEvent,
QKeyEvent,QKeyPressEvent,QKeyReleaseEvent,
QPaintEvent....................
I guess all the events should be sent to the current focus widget.
(I don't know the Qt's event mechanism,so here is guess.)
by zhangshaoyan at May 28,2015.
A system I can think about is a subscriber-notifier model.
You may have something that handles your sensors (for example, a thread that polls on it to see if something happened).
When it detects something, the task should raise a mechanism in order to let the outer world be aware :
this is thenotification
process. 通知
On the other side, only the people who are interested in your sensor should be notified,
thus, asubscription
method should be here to take care of this.订阅
Event driven architecture simply means, that the main loop AKA event loop does not understand much about the data a program processes.
It understands only enough, that it can dispatch the right events for the data.
So for example, if event is triggered by data coming from a socket,
all the event loop needs to know is, what callback to call, when data comes from that particular socket.
Typically the event loop is in some library, such as libevent.
So application code consists of just setup code and event handlers which are called by the event loop in the library.
Since you mention threads:
a classic simple event driven application is single threaded.
Each event handler or callback just does its thing as fast as it can, when it gets called, and returns.
Blocking or waiting or sleeping is a big no no, it will block all other events!
Threads are often used, when there is some processing which takes long time.
If it were done in the main thread with event loop,
the long operation would have to be chopped into small pieces,
so other events could be handled too.
So it's simpler to have a worker thread, which can do the processing without interfering with event processing,
and then generate event for main event loop when done.
Other case of using threads is, when there is something which must block.
It may for example be some other library, which only provides a blocking API.
If that API was to be used from the main thread event loop, it would block other events.
Solution is to use that library from another thread,
which can block,
and then generate event for the main event loop when there's something interesting for other parts of the application.But in a sense, event driven architecture is sort of opposite of multi-threaded architecture:
- In straightforward multi-threaded architecture,
- each thread waits for one kind of thing to process (a wait condition or a blocking queue or a blocking socket read or whatever,
- possibly with timeout to periodically check something), then does the processing, possibly signals other threads,
- and goes back to waiting. One thread does one thing, and there's a thread for each different kind of thing to do.
- In event driven architecture there's just one main event loop (usually from a library)
- which waits for all kinds of events and calls handlers,
- all in the same thread. One thread does everything,
- and there's a non-blocking event handler for each different things to do.
- The good thing about this is, no synchronization is needed, because it's all in one thread,
- which avoids all-too-common multi-threading bugs, keeps code simpler and avoid synchronization overhead.
- Downside is not taking advantage of multiple CPU cores, and risk of blocking event loop if developer is careless.
Of course a complex application can have several event loops in different threads,
and also threads which do just single thing, so these can be mixed.