Libevent使用范例及代码说明

邮差的信 提交于 2020-01-25 20:29:33

利用libevent实现有数据来时,执行ReadBuffer函数,支持多线程。

static EventApiParameter parameter;
memset((void *)&parameter, 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 *)&parameter, 0, sizeof(parameter));
    memcpy((void *)&parameter, 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(&parameter.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 *)&parameter, 0, sizeof(parameter));
    EventApiParameter *p_parameter = ( EventApiParameter *)arg;
    pthread_mutex_lock(&p_parameter->mutex);
    memcpy((void *)&parameter, 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, &parameter.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(&parameter.mutex);
	pthread_create(&thread,NULL,EventHandleThread,(void*)&parameter);
	pthread_detach(thread);
    pthread_cond_wait(&parameter.cond,&parameter.mutex);
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!