多线程应用libevent练习---流程图
2016-11-23 22:11:23 64 举报
AI智能生成
登录查看完整内容
这是一个linux下多线程应用Libevent的流程图。 其实从设计和效率上来说,这个多线程用法是不好的,应该使用单线程多进程的设计。 此代码纯为练习C用。
作者其他创作
大纲/内容
start_libevent_thread
初始化
初始化recv收包缓存g_Buffer_Temp
初始化sockfd哈希表g_ConnBuffer_Table
初始化数据包缓存g_Queue
typedef struct BufferUnit{\tint buffer_type;\tvoid *ptr;\tevutil_socket_t sockfd; struct BufferUnit* prev; struct BufferUnit* next;}Buffer_Unit;
void *ptr
typedef struct Buffer_Read{\tevutil_socket_t sockfd;\tBUFF_READ_T *buffer;}Buffer_Read;
typedef struct Buffer_Conn{\tevutil_socket_t sockfd;\tchar ip_addr[IP_ADDR_LEN];\tstruct bufferevent \t*bev;}Buffer_Conn;
初始化python线程设置
PyEval_InitThreads
PyThreadState* state=PyEval_SaveThread()
线程 RecvThread
evthread_use_pthreads
event_base_new
event_set_fatal_callback
致命错误回调函数OnFatalErr_CB
初始化 struct sockaddr_in fsin 设置端口和协议族
evconnlistener_new_bind
连接事件回调OnNewConnect_CB
bufferevent_socket_new创建bufferevent对象evobj
bufferevent_setcb设置回调函数
收到数据回调OnRead_CB
取得数据缓存指针struct evbuffer *input=bufferevent_get_input(evobj);
创建一个新的缓存对象 struct evbuffer *buffer=evbuffer_new();
创建一个读取缓存包并压入g_Queue
pthread_mutex_lock
pthread_mutex_unlock
发送数据回调OnWrite_CB
触发事件回调OnEvent_CB
closeconnect(sockfd)
将socket描述符client压入哈希表g_ConnBuffer_Table
创建一个连接缓存包并压入g_Queue
evconnlistener_set_error_cb
连接失败回调OnAcceptError_CB
evsignal_new & event_add 设置中断事件的回调
触发信号回调OnSignal_INT_CB
event_base_dispatch 进入事件循环
结束循环,释放资源
线程 ScriptThread
获取Python全局解释器锁 PyGILState_STATE state = PyGILState_Ensure();
加载需要调用的Python模块和函数对象
创建局部变量 Buffer_Queue *queue_loop=Create_Queue
进入 while(1) 无限循环
将g_Queue当前的数据全部复制给queue_loop
判断是否有数据赋值给 queue_loop
cnt_unit<=0
睡眠usleep(1000)
进入下一次循环continue
cnt_unit>0
unit=Buffer_Pop_Queue(queue_loop);
进入while(unit)循环
如果unit是连接缓存包
获取包指向的sockfd、evobj、ip_addr
0==strlen(ip_addr) 处理断线包
调用Python函数DisConnect
0!=strlen(ip_addr) 处理新连接包
记录玩家sockfd并与evobj关联 record_sockfd_libevent
调用Python函数Login
释放unit资源 Free_Queue_Unit_Conn
如果unit是读取缓存包
获取包指向的sockfd、struct evbuffer * buffer
初始化收包缓存 g_Buffer_Temp
将数据流以BUFFSIZE为长度单位,将数据从buffer复制给g_Buffer_Temp,再压入解包队列
判断并试图进入解包逻辑 while( get_validunpack(sockfd) > 0 )
获取协议号 proto=getbuffer_unpack(sockfd)
调用Python函数OnCommand,由Python层操作协议
解包
UnPackInt
UnPackString
发送请求
PacketPrepare
PacketInt
PacketString
PacketSend
释放unit资源 Free_Queue_Unit_Read(unit);
循环末尾再把新的unit弹出来 unit=Buffer_Pop_Queue(queue_loop);
若开启了时间统计,统计时间并将结果作为参数调用Python函数 LoopStatistics_Libev
短暂睡眠usleep(100),然后重新进入while(1)循环
释放生成的Python模块和函数对象
释放python全局解释器锁 PyGILState_Release(state)
Thread_Wait等待两个线程结束
PyEval_AcquireLock()
PyThreadState_Swap(state)
进入断线阶段1
创建一个连接缓存包并压入队列
进入断线阶段2
把sockfd从解包队列移除 remove_sockfd(sockfd)
释放evobj对象 bufferevent_free(evobj)
0 条评论
回复 删除
下一页