事件驱动设计c

pig*_*ack 5 c events event-driven-design

这是一个小小的理论问题.想象一下装满传感器的设备.现在,如果传感器x检测到某些东西,应该发生一些事情.同时,如果检测到其他东西,例如两个传感器检测到两个不同的东西,则该设备必须表现不同.

从网页设计(所以javascript)我学习了事件,例如(使用jquery)$(".x").on("click", function(){})或angularjs $scope.watch("name_of_var", function()).

是否有可能在C中复制此行为,而不使用复杂的库?

谢谢.

Ani*_*nge 7

我假设您拥有一个嵌入式系统,可以在单独的线程中访问中断或主要事件循环,否则这是不可能的。

事件处理的基本模型如下:

#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;
   while(1){
       while(event == NOEVENT)event=GetEvents();
       handler = AllEvents[event].handler;
       handler();/*perform on an event*/
  }
}
Run Code Online (Sandbox Code Playgroud)


Rer*_*ito 5

我能想到的一个系统是用户通知模型.您可能有一些东西可以处理您的传感器(例如,在其上轮询以查看是否发生了某些事情的线程).当它检测到某些东西时,任务应该引发一个机制,让外界知道:这是通知过程.
另一方面,只应通知对您的传感器感兴趣的人,因此,应在此处使用订阅方法来处理此问题.

现在,困难的部分进来.当传感器处理程序通知世界时,它不能花太多时间这样做,否则它可能会错过其他事件.因此,必须具有专用于通知过程的任务(或线程).另一方面,订户希望在接收到这样的通知事件时更新他们的一些数据.这显然是一个异步过程,因此订阅者必须为通知程序线程提供回调.
最后,你应该用时间戳标记你的事件,这样接收者就会知道他们得到的事件是否过时而且是否应该丢弃它.
最后的事情可能看起来像下面的代码:


数据结构

/*
 * Some data structures to begin with
 */
struct event;
struct notifier;
struct subscription;
struct notify_sched;


typedef int (*notify_cbck)(struct event *evt, void *private);
/*
 *@type : a value to show the type of event
 *@t : the timestamp of the event
 *@value : a pointer towards the event data
 */
struct event {
    int type;
    struct timeval t; // the timestamp
    void *value;
};

/*
 * @type : the type in which the subscriber is interested
 * @cb : the callback that should be run when an event occur
 * @cb_data : the data to provide to the callback
 * @next,prev : doubly-linked list
 */
struct subscription {
    int type;
    notify_cbck cb;
    void *cb_data;
    struct subscription *next, *prev;
};

/*
 * This structure gathers the subscriptions of a given type.
 * @type : the event type
 * @subs : the subscription list
 * @mutex : a mutex to protect the list while inserting/removing subscriptions
 * @next,prev : link to other typed subscriptions
 */

struct typed_subscription {
    int type;
    struct subscription *subs;
    mutex_t mutex;
    struct typed_subscription *next, *prev;
};

/*
 * @magic : the ID of the event producer
 * @t_subs : the typed_subscription list
 * @mutex : a mutex to protect data when (un)registering new types to the producer
 * @next, prev : doubly-linked list ...
 */
struct notifier {
    int magic;
    struct typed_subscription *t_subs;
    mutex_t mutex;
    struct notifier *next, *prev;
};

/*
 * @ntf : the notifiers list
 * @mutex : a mutex to protect the ntf list
 * @th : something to identify the task that hosts the scheduler
 */
struct notify_sched {
    struct notifier *ntf;
    mutex_t mutex;
    pthread_t th; // I assume it's a classic pthread in this example.
};
Run Code Online (Sandbox Code Playgroud)

我现在没有时间完成我的回答,稍后我将对其进行编辑,为您提供完整的示例.但是从数据结构开始,你应该得到一些想法.希望无论如何这有点帮助.