下面是一个使用 Libevent 的多线程接收数据的示例程序。该程序使用了 Libevent 的线程支持,并创建了多个线程来同时接收数据。
```c
#include <stdio.h>
#include <stdlib.h>
#include <event2/event.h>
#include <event2/thread.h>
#define THREAD_COUNT 4
void event_callback(evutil_socket_t fd, short events, void *arg) {
char buffer[1024];
int recv_size;
// 接收数据
recv_size = recv(fd, buffer, sizeof(buffer), 0);
if (recv_size > 0) {
// 处理接收到的数据
printf("Received data: %.*s\n", recv_size, buffer);
} else if (recv_size == 0) {
// 连接关闭
printf("Connection closed\n");
} else {
// 接收错误
printf("Error in receiving data\n");
}
}
void* thread_func(void *arg) {
struct event_base *base = event_base_new();
struct event *ev;
int listen_fd = *((int *)arg);
// 创建事件
ev = event_new(base, listen_fd, EV_READ | EV_PERSIST, event_callback, NULL);
// 添加事件到事件循环
event_add(ev, NULL);
// 启动事件循环
event_base_dispatch(base);
// 清理资源
event_free(ev);
event_base_free(base);
return NULL;
}
int main() {
struct event_config *config;
struct event_base *base;
pthread_t threads[THREAD_COUNT];
int listen_fd;
// 初始化 Libevent 线程支持
evthread_use_pthreads();
// 创建 event_base
config = event_config_new();
event_config_set_flag(config, EVENT_BASE_FLAG_STARTUP_IOCP);
base = event_base_new_with_config(config);
// 创建监听套接字
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
// 设置监听套接字的选项和绑定等操作...
// 创建多个线程来处理事件
for (int i = 0; i < THREAD_COUNT; i++) {
pthread_create(&threads[i], NULL, thread_func, &listen_fd);
}
// 主线程进入事件循环
event_base_dispatch(base);
// 等待子线程结束
for (int i = 0; i < THREAD_COUNT; i++) {
pthread_join(threads[i], NULL);
}
// 清理资源
event_base_free(base);
event_config_free(config);
close(listen_fd);
return 0;
}
```
在这个示例程序中,我们创建了一个主线程和多个工作线程。主线程用于创建 Libevent 的事件循环基础 `event_base`,并进入事件循环。每个工作线程都创建了一个独立的 `event_base`,并在其中创建事件 `ev`,然后将其添加到事件循环中。
当有数据到达监听套接字时,每个工作线程的回调函数 `event_callback` 将会被触发,用于接收和处理数据。