欢迎光临
我们一直在努力

事件驱动架构代码分析(c代码演示例子)


author: hjjdebug date: 2026年 01月 23日 星期五 11:24:25 CST descrip: 事件驱动架构代码分析(c代码演示例子)


文章目录

  • 0. 并发程序
  • 1. 事件驱动模型与轮询机制有何区别?
  • 2. 事件驱动模型与中断机制有何区别?
  • 3. 主函数说明
  • 4 参考代码:
    • 4.1 event_driver.h
    • 4.2 event_driver.c
    • 4.3 main.c
    • 4.4 Makefile
  • 5. 程序执行结果

0. 并发程序

有时候, 程序不是顺序执行的,而是并发执行的. 命令行程序很多是顺序执行的,下面的情况则是属于并发执行的.

  • gui界面, 不同的按钮点击需要执行不同的操作函数.
  • 系统层面, 不同设备的I/O, 文件的读写, 当系统完成相应操作时,会通知应用读写.
  • 服务器程序, 当web 服务器接受到不同的http请求,会触发相应的服务响应程序.
  • 顺序执行直观的感受就是一条条的顺序执行语句. 并发执行就是能够同时执行不同的命令. 如果用语句来表达,可用switch…case 来代替. 来不同的数据,用不同的方式来处理. 多分枝选择结构,散转结构.

    事件驱动模型, 不再是顺序执行,而是并发执行. 当不同的事件到达,用不同的处理方式

    1. 事件驱动模型与轮询机制有何区别?

    事件驱动模型: 当事件发生时,事件会被发送到事件池中,系统发现有事件,会主动调用相应的处理函数. 轮询模型:轮询模型往往让人想到驱动中的轮询各设备的状态信息,主动查询每一个信息源,是否准备好发送数据或接受数据 每次都查询对方状态,容易造成cpu资源浪费.

    2. 事件驱动模型与中断机制有何区别?

    中断是一种硬件机制, 当中断源有信号时,cpu保存现场执行中断服务程序,然后再恢复现场从中断点执行. 而事件驱动是一种软机制,当事件发生时,系统监测到事件后去执行相应的事件响应程序. 由此我们知道,事件驱动的核心是, 有事件发生了,放到池子中. 程序处理的是池子中的事件

    可结合具体代码来理解上边的概念:

    3. 主函数说明

    创建一个事件循环对象. 创建了若干个事件,并向事件循环对象post 事件 观察事件被处理的情况.

    演示代码没有采用switch-case语句. 那它是怎么做到的散转? 因为事件自带handler, 不需要查找,也不需要散转. 如果事件不带handler, 而用注册type-handler 方式呢? 那可以用查找找handler,不用散转. 因为散转在某些情况下(情况复杂,代码长时)是一种不好的结构, 而在逻辑比较简单的情况下,又是一种好结构. 知道的都懂,我就不展开了.

    注意以下几点:

  • 事件是自带handler 的, 还带有优先级, 处理时间 及信息.
  • 事件循环对象对每一种类型都准备了事件池.
  • 主线程向事件池post 事件, 接口是向event_loop 对象post 事件
  • 用一个执行线程去专门处理各种事件.
  • 展现了事件驱动模型中事件源与处理逻辑解耦的特点 本来你只能看到main 函数, 下面的逻辑被封装成库.这里的演示代码则让你看到了所有细节.

    在实际应用中,事件驱动模型可以是单线程的,也可以是多线程的。 单线程事件驱动模型通过事件循环和回调函数来处理事件, 而多线程事件驱动模型则可能结合线程池来提高处理能力。 无论哪种方式,事件驱动模型的核心思想都是通过事件来驱动程序的执行,实现并发处理

    代码略微有点长,是考虑了实际的使用场景和可扩展能力. 但逻辑还是比较简单的. 容易看懂.

    4 参考代码:

    4.1 event_driver.h

    #ifndef EVENT_DRIVER_H
    #define EVENT_DRIVER_H

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <time.h>
    #include <pthread.h>

    // 事件类型定义
    typedef enum {
    TIMER_EVENT,
    NETWORK_EVENT,
    USER_INPUT_EVENT,
    SYSTEM_EVENT,
    CUSTOM_EVENT,
    MAX_EVENT_TYPES
    } EventType;

    // 事件优先级
    typedef enum {
    LOW_PRIORITY,
    NORMAL_PRIORITY,
    HIGH_PRIORITY
    } EventPriority;

    // 事件状态
    typedef enum {
    EVENT_PENDING,
    EVENT_PROCESSING,
    EVENT_COMPLETED,
    EVENT_CANCELLED
    } EventStatus;

    // 事件处理函数类型
    typedef void (*EventHandler)(void* data);

    // 事件结构体, 包含handler 指针及数据, 也包含next指针可构成链表
    // 属性定义的多了点,所以代码显得才有点长
    typedef struct Event {
    int id;
    EventType type;
    EventPriority priority;
    EventStatus status;
    time_t created_time;
    time_t scheduled_time;
    EventHandler handler;
    void* data;
    size_t data_size;
    struct Event* next;
    } Event;

    // 事件队列结构体,管理事件队列
    typedef struct {
    Event* head;
    Event* tail;
    int size;
    pthread_mutex_t mutex; //mutex 为添加删除事件提供互斥机制
    } EventQueue;

    // 事件循环结构体, 存储有各种类型的事件队列(其实用一个队列也可以),线程运行状态及线程id
    typedef struct {
    EventQueue* queues[MAX_EVENT_TYPES]; //多种类型事件队列指针
    int running; //thread 的运行状态
    pthread_t thread; //thread 的ID
    } EventLoop;

    // 事件循环API
    EventLoop* create_event_loop();
    void destroy_event_loop(EventLoop* loop);
    int start_event_loop(EventLoop* loop);
    int stop_event_loop(EventLoop* loop);
    int post_event(EventLoop* loop, Event* event);
    int post_delayed_event(EventLoop* loop, Event* event, int delay_ms);
    Event* create_event(EventType type, EventHandler handler, void* data, size_t data_size);
    void destroy_event(Event* event);

    // 工具函数
    const char* event_type_to_string(EventType type);
    const char* event_priority_to_string(EventPriority priority);
    const char* event_status_to_string(EventStatus status);

    #endif

    4.2 event_driver.c

    #include "event_driver.h"
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <unistd.h>

    // 创建事件队列
    EventQueue* create_event_queue() {
    EventQueue* queue = (EventQueue*)malloc(sizeof(EventQueue));
    if (!queue) return NULL;

    queue->head = NULL;
    queue->tail = NULL;
    queue->size = 0;
    pthread_mutex_init(&queue->mutex, NULL);

    return queue;
    }

    // 销毁事件队列
    void destroy_event_queue(EventQueue* queue) {
    if (!queue) return;

    pthread_mutex_destroy(&queue->mutex);
    free(queue);
    }

    // 创建事件循环
    EventLoop* create_event_loop() {
    EventLoop* loop = (EventLoop*)malloc(sizeof(EventLoop));
    if (!loop) return NULL;

    for (int i = 0; i < MAX_EVENT_TYPES; i++) {
    loop->queues[i] = create_event_queue();
    if (!loop->queues[i]) {
    // 清理已分配的队列
    for (int j = 0; j < i; j++) {
    destroy_event_queue(loop->queues[j]);
    }
    free(loop);
    return NULL;
    }
    }

    loop->running = 0;
    return loop;
    }

    // 销毁事件循环
    void destroy_event_loop(EventLoop* loop) {
    if (!loop) return;

    for (int i = 0; i < MAX_EVENT_TYPES; i++) {
    if (loop->queues[i]) {
    destroy_event_queue(loop->queues[i]);
    }
    }

    free(loop);
    }

    // 将事件添加到队列(按优先级排序)
    void enqueue_event(EventQueue* queue, Event* event) {
    if (!queue || !event) return;

    pthread_mutex_lock(&queue->mutex);

    // 如果队列为空
    if (!queue->head) {
    queue->head = event;
    queue->tail = event;
    event->next = NULL;
    } else {
    // 按优先级插入事件
    Event* current = queue->head;
    Event* prev = NULL;

    // 找到插入位置
    while (current && current->priority >= event->priority) {
    prev = current;
    current = current->next;
    }

    // 插入到队列头部
    if (!prev) {
    event->next = queue->head;
    queue->head = event;
    } else {
    // 插入到中间或尾部
    prev->next = event;
    event->next = current;

    // 如果插入到尾部
    if (!current) {
    queue->tail = event;
    }
    }
    }

    queue->size++;
    pthread_mutex_unlock(&queue->mutex);
    }

    // 从队列中取出事件
    Event* dequeue_event(EventQueue* queue) {
    if (!queue || !queue->head) return NULL;

    pthread_mutex_lock(&queue->mutex);

    Event* event = queue->head;
    queue->head = event->next;

    if (!queue->head) {
    queue->tail = NULL;
    }

    queue->size;
    pthread_mutex_unlock(&queue->mutex);

    return event;
    }

    // 创建事件
    Event* create_event(EventType type, EventHandler handler, void* data, size_t data_size) {
    Event* event = (Event*)malloc(sizeof(Event));
    if (!event) return NULL;

    event->id = rand();
    event->type = type;
    event->priority = NORMAL_PRIORITY;
    event->status = EVENT_PENDING;
    event->created_time = time(NULL);
    event->scheduled_time = event->created_time;
    event->handler = handler;
    event->data_size = data_size;
    event->next = NULL;

    if (data && data_size > 0) {
    event->data = malloc(data_size);
    if (event->data) {
    memcpy(event->data, data, data_size);
    } else {
    free(event);
    return NULL;
    }
    } else {
    event->data = NULL;
    }

    return event;
    }

    // 销毁事件
    void destroy_event(Event* event) {
    if (!event) return;

    if (event->data) {
    free(event->data);
    }

    free(event);
    }

    // 发布事件
    int post_event(EventLoop* loop, Event* event) {
    if (!loop || !event || !loop->running) return 1;

    if (event->type >= MAX_EVENT_TYPES) {
    return 1;
    }

    enqueue_event(loop->queues[event->type], event);
    return 0;
    }

    // 发布延迟事件
    int post_delayed_event(EventLoop* loop, Event* event, int delay_ms) {
    if (!loop || !event || !loop->running) return 1;

    if (event->type >= MAX_EVENT_TYPES) {
    return 1;
    }

    event->scheduled_time = time(NULL) + (delay_ms / 1000);
    enqueue_event(loop->queues[event->type], event);
    return 0;
    }

    // 事件循环处理函数
    void* event_loop_thread(void* arg) {
    EventLoop* loop = (EventLoop*)arg;

    while (loop->running) {
    int has_events = 0;
    time_t current_time = time(NULL);

    // 按优先级顺序处理事件
    for (int priority = HIGH_PRIORITY; priority >= LOW_PRIORITY; priority) {
    for (int type = 0; type < MAX_EVENT_TYPES; type++) {
    EventQueue* queue = loop->queues[type];
    if (!queue) continue; //该类型没有事件,查下一类型

    pthread_mutex_lock(&queue->mutex);
    Event* current = queue->head;
    Event* prev = NULL;

    // 遍历队列查找可处理的事件
    while (current) {
    // 检查事件是否已到执行时间
    if (current_time >= current->scheduled_time) {
    // 从队列中移除事件
    if (prev) {
    prev->next = current->next;
    } else {
    queue->head = current->next;
    }

    if (current == queue->tail) {
    queue->tail = prev;
    }

    queue->size;

    // 处理事件
    current->status = EVENT_PROCESSING;
    if (current->handler) {
    current->handler(current->data);
    }
    current->status = EVENT_COMPLETED;

    // 保存下一个节点
    Event* next = current->next;

    // 销毁事件
    destroy_event(current);

    current = next;
    has_events = 1;
    } else {
    prev = current;
    current = current->next;
    }
    }

    pthread_mutex_unlock(&queue->mutex);
    }
    }

    // 如果没有事件,短暂休眠
    if (!has_events) {
    usleep(10000); // 10ms
    }
    } //事件循环

    return NULL;
    }

    // 启动事件循环
    int start_event_loop(EventLoop* loop) {
    if (!loop) return 1;

    loop->running = 1;
    int result = pthread_create(&loop->thread, NULL, event_loop_thread, loop);
    return result;
    }

    // 停止事件循环
    int stop_event_loop(EventLoop* loop) {
    if (!loop) return 1;

    loop->running = 0;
    pthread_join(loop->thread, NULL);
    return 0;
    }

    // 工具函数实现
    const char* event_type_to_string(EventType type) {
    switch (type) {
    case TIMER_EVENT: return "TIMER_EVENT";
    case NETWORK_EVENT: return "NETWORK_EVENT";
    case USER_INPUT_EVENT: return "USER_INPUT_EVENT";
    case SYSTEM_EVENT: return "SYSTEM_EVENT";
    case CUSTOM_EVENT: return "CUSTOM_EVENT";
    default: return "UNKNOWN_EVENT";
    }
    }

    const char* event_priority_to_string(EventPriority priority) {
    switch (priority) {
    case LOW_PRIORITY: return "LOW_PRIORITY";
    case NORMAL_PRIORITY: return "NORMAL_PRIORITY";
    case HIGH_PRIORITY: return "HIGH_PRIORITY";
    default: return "UNKNOWN_PRIORITY";
    }
    }

    const char* event_status_to_string(EventStatus status) {
    switch (status) {
    case EVENT_PENDING: return "PENDING";
    case EVENT_PROCESSING: return "PROCESSING";
    case EVENT_COMPLETED: return "COMPLETED";
    case EVENT_CANCELLED: return "CANCELLED";
    default: return "UNKNOWN_STATUS";
    }
    }

    4.3 main.c

    #include "event_driver.h"
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>

    // 示例事件处理函数
    void timer_event_handler(void* data) {
    int* timer_id = (int*)data;
    printf("[TIMER_EVENT] 定时器 #%d 触发 at %ld\\n", *timer_id, time(NULL));
    }

    void network_event_handler(void* data) {
    char* message = (char*)data;
    printf("[NETWORK_EVENT] 网络消息: %s at %ld\\n", message, time(NULL));
    }

    void user_input_event_handler(void* data) {
    char* input = (char*)data;
    printf("[USER_INPUT_EVENT] 用户输入: %s at %ld\\n", input, time(NULL));
    }

    void system_event_handler(void* data) {
    char* event_name = (char*)data;
    printf("[SYSTEM_EVENT] 系统事件: %s at %ld\\n", event_name, time(NULL));
    }

    void custom_event_handler(void* data) {
    char* custom_data = (char*)data;
    printf("[CUSTOM_EVENT] 自定义事件: %s at %ld\\n", custom_data, time(NULL));
    }

    int main() {
    printf("=== 复杂事件驱动模型示例 ===\\n");

    // 创建事件循环对象, 所谓对象就是结构变量,把一些变量放在一起方便我们采用!!
    EventLoop* loopObj = create_event_loop();
    if (!loopObj) {
    printf("创建事件循环失败\\n");
    return 1;
    }

    // 启动事件循环, 会启动event_loop_thread 线程
    if (start_event_loop(loopObj) != 0) {
    printf("启动事件循环失败\\n");
    destroy_event_loop(loopObj);
    return 1;
    }

    printf("事件循环已启动…\\n\\n");

    // 创建并发布各种事件
    // 1. 定时器事件
    int timer_id = 1001;
    Event* timer_event = create_event(TIMER_EVENT, timer_event_handler, &timer_id, sizeof(timer_id));
    if (timer_event) {
    timer_event->priority = HIGH_PRIORITY;
    post_event(loopObj, timer_event); //需要提供event_loop 对象地址
    }

    // 2. 延迟定时器事件
    int delayed_timer_id = 2001;
    Event* delayed_timer_event = create_event(TIMER_EVENT, timer_event_handler, &delayed_timer_id, sizeof(delayed_timer_id));
    if (delayed_timer_event) {
    delayed_timer_event->priority = NORMAL_PRIORITY;
    post_delayed_event(loopObj, delayed_timer_event, 2000); // 2秒后执行
    }

    // 3. 网络事件
    char network_message[] = "数据包已接收";
    Event* network_event = create_event(NETWORK_EVENT, network_event_handler, network_message, strlen(network_message) + 1);
    if (network_event) {
    network_event->priority = HIGH_PRIORITY;
    post_event(loopObj, network_event);
    }

    // 4. 用户输入事件
    char user_input[] = "Hello World";
    Event* input_event = create_event(USER_INPUT_EVENT, user_input_event_handler, user_input, strlen(user_input) + 1);
    if (input_event) {
    input_event->priority = NORMAL_PRIORITY;
    post_event(loopObj, input_event);
    }

    // 5. 系统事件
    char system_event_name[] = "系统启动完成";
    Event* sys_event = create_event(SYSTEM_EVENT, system_event_handler, system_event_name, strlen(system_event_name) + 1);
    if (sys_event) {
    sys_event->priority = HIGH_PRIORITY;
    post_event(loopObj, sys_event);
    }

    // 6. 自定义事件
    char custom_data[] = "自定义数据处理";
    Event* custom_event = create_event(CUSTOM_EVENT, custom_event_handler, custom_data, strlen(custom_data) + 1);
    if (custom_event) {
    custom_event->priority = LOW_PRIORITY;
    post_event(loopObj, custom_event);
    }

    // 7. 另一个延迟事件
    char delayed_message[] = "延迟网络消息";
    Event* delayed_network_event = create_event(NETWORK_EVENT, network_event_handler, delayed_message, strlen(delayed_message) + 1);
    if (delayed_network_event) {
    delayed_network_event->priority = NORMAL_PRIORITY;
    post_delayed_event(loopObj, delayed_network_event, 3000); // 3秒后执行
    }

    printf("已发布所有事件,等待处理…\\n");

    // 运行一段时间
    sleep(5);

    // 停止事件循环
    stop_event_loop(loopObj);

    // 销毁事件循环
    destroy_event_loop(loopObj);

    printf("\\n事件循环已停止,程序结束。\\n");
    return 0;
    }

    4.4 Makefile

    CC = gcc
    CFLAGS = Wall Wextra pthread
    SRCDIR = .
    SOURCES = event_driver.c main.c
    OBJECTS = $(SOURCES:.c=.o)
    TARGET = event_driver_demo

    .PHONY: all clean

    all: $(TARGET)

    $(TARGET): $(OBJECTS)
    $(CC) $(CFLAGS) o $@ $^

    %.o: %.c
    $(CC) $(CFLAGS) c $< o $@

    clean:
    rm f $(OBJECTS) $(TARGET)

    run: $(TARGET)
    ./$(TARGET)

    5. 程序执行结果

    $ ./event_driver_demo === 复杂事件驱动模型示例 === 事件循环已启动…

    已发布所有事件,等待处理… [TIMER_EVENT] 定时器 #1001 触发 at 1769139890 [NETWORK_EVENT] 网络消息: 数据包已接收 at 1769139890 [USER_INPUT_EVENT] 用户输入: Hello World at 1769139890 [SYSTEM_EVENT] 系统事件: 系统启动完成 at 1769139890 [CUSTOM_EVENT] 自定义事件: 自定义数据处理 at 1769139890 [TIMER_EVENT] 定时器 #2001 触发 at 1769139892 [NETWORK_EVENT] 网络消息: 延迟网络消息 at 1769139893

    事件循环已停止,程序结束。

    赞(0)
    未经允许不得转载:171主机测评 » 事件驱动架构代码分析(c代码演示例子)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址