利用libevent实现有数据来时,执行ReadBuffer函数,支持多线程。
static EventApiParameter parameter;
memset((void *)¶meter, 0, sizeof(parameter));
parameter.agent_socket.port = port;
//parameter.write_function_point = WriteBuffer;
parameter.read_function_point = ReadBuffer;
parameter.timer=0;
//event和event_base是libevent的两个基础结构体
struct event ev;
struct event_base *base;
//申请一个新的event_base
base = event_base_new();
//设置ev,将fd回调函数OnAccept以及回调函数参数arg赋值到ev结构中
//event_set->event_assign
event_set(&ev, fd, EV_READ|EV_PERSIST, OnAccept, (void *)parameter);
//将base赋值到ev结构中,ev->ev_base = base
event_base_set(base, &ev);
//主要作用是将ev结构添加到队列中
//event_add->event_add_nolock_->event_queue_insert_inserted
event_add(&ev, NULL);
//run forever
//event_dispatch 是程序的主体循环,我们注册的回调函数就在该循环体中执行
/*event_base_dispatch->event_loop->event_base_loop->event_process_active->event_process_active_single_queue->evcb_callback*/
event_base_dispatch(base);
//never running
//正常情况下不会走到这里,循环退出时会走到这里,回收资源
event_del(&ev);
event_base_free(base);
void OnAccept(int fd, short event, void* arg)
{
struct sockaddr_in remote_addr;
EventApiParameter parameter;
memset((void *)¶meter, 0, sizeof(parameter));
memcpy((void *)¶meter, arg, sizeof(parameter));
int sin_size=sizeof(struct sockaddr_in);
int new_fd = accept(fd, (struct sockaddr*) &remote_addr, (socklen_t*)&sin_size);
if(new_fd < 0){
return;
}
//int high;
//evutil_make_listen_socket_reuseable(new_fd);
//evutil_make_socket_nonblocking(new_fd);
//setsockopt(new_fd, SOL_SOCKET, SO_REUSEPORT,
//(const char *)&high, sizeof(int));
memcpy(¶meter.agent_socket.addr, &remote_addr, sizeof(remote_addr));
if (NULL != parameter.accept_function_point)
{
parameter.accept_function_point(remote_addr);
}
parameter.agent_socket.fd = new_fd;
AcceptNewThread(parameter);
}
void* EventHandleThread(void* arg){
//long long_fd = (long)arg;
//int fd = (int)long_fd;
EventApiParameter parameter;
memset((void *)¶meter, 0, sizeof(parameter));
EventApiParameter *p_parameter = ( EventApiParameter *)arg;
pthread_mutex_lock(&p_parameter->mutex);
memcpy((void *)¶meter, p_parameter, sizeof(parameter));
pthread_cond_signal(&p_parameter->cond);
pthread_mutex_unlock(&p_parameter->mutex);
int fd = parameter.agent_socket.fd;
if(fd<0){
return 0;
}
struct event_base *base = event_base_new();
if (NULL == base)
{
return 0;
}
//struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
struct bufferevent *bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);
if (NULL == bev)
{
return 0;
}
//set timer
if (parameter.timer)
{
CreateTimeoutEvent(base, bev);
}
bufferevent_setcb(bev, parameter.read_function_point, NULL, EventError, ¶meter.agent_socket);
bufferevent_enable(bev, EV_READ);
struct timeval write_tv = {1,0};
bufferevent_set_timeouts (bev, NULL, &write_tv);
event_base_dispatch(base);
event_base_free(base);
return 0;
}
void AcceptNewThread(EventApiParameter parameter){
pthread_t thread;
parameter.mutex=PTHREAD_MUTEX_INITIALIZER;
parameter.cond=PTHREAD_COND_INITIALIZER;
pthread_mutex_lock(¶meter.mutex);
pthread_create(&thread,NULL,EventHandleThread,(void*)¶meter);
pthread_detach(thread);
pthread_cond_wait(¶meter.cond,¶meter.mutex);
}
来源:CSDN
作者:oria2006
链接:https://blog.csdn.net/oria2006/article/details/104019054