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. 并发程序
有时候, 程序不是顺序执行的,而是并发执行的. 命令行程序很多是顺序执行的,下面的情况则是属于并发执行的.
顺序执行直观的感受就是一条条的顺序执行语句. 并发执行就是能够同时执行不同的命令. 如果用语句来表达,可用switch…case 来代替. 来不同的数据,用不同的方式来处理. 多分枝选择结构,散转结构.
事件驱动模型, 不再是顺序执行,而是并发执行. 当不同的事件到达,用不同的处理方式
1. 事件驱动模型与轮询机制有何区别?
事件驱动模型: 当事件发生时,事件会被发送到事件池中,系统发现有事件,会主动调用相应的处理函数. 轮询模型:轮询模型往往让人想到驱动中的轮询各设备的状态信息,主动查询每一个信息源,是否准备好发送数据或接受数据 每次都查询对方状态,容易造成cpu资源浪费.
2. 事件驱动模型与中断机制有何区别?
中断是一种硬件机制, 当中断源有信号时,cpu保存现场执行中断服务程序,然后再恢复现场从中断点执行. 而事件驱动是一种软机制,当事件发生时,系统监测到事件后去执行相应的事件响应程序. 由此我们知道,事件驱动的核心是, 有事件发生了,放到池子中. 程序处理的是池子中的事件
可结合具体代码来理解上边的概念:
3. 主函数说明
创建一个事件循环对象. 创建了若干个事件,并向事件循环对象post 事件 观察事件被处理的情况.
演示代码没有采用switch-case语句. 那它是怎么做到的散转? 因为事件自带handler, 不需要查找,也不需要散转. 如果事件不带handler, 而用注册type-handler 方式呢? 那可以用查找找handler,不用散转. 因为散转在某些情况下(情况复杂,代码长时)是一种不好的结构, 而在逻辑比较简单的情况下,又是一种好结构. 知道的都懂,我就不展开了.
注意以下几点:
展现了事件驱动模型中事件源与处理逻辑解耦的特点 本来你只能看到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
事件循环已停止,程序结束。



