co_routine.h
#ifndef __CO_ROUTINE_H__
#define __CO_ROUTINE_H__
#include <stdint.h>
#include <sys/poll.h>
#include <pthread.h>
//1.struct
struct stCoRoutine_t;//協程的結構體 用來存儲協程相關的資訊 具體含義會在 co_routine.cpp 給出
struct stShareStack_t;//共享棧結構體 存儲共享棧相關資訊 具體資訊會在 co_routine_inner.h 給出
struct stCoRoutineAttr_t // 用來初始化共享棧時使用的結構體。
{
int stack_size; //棧的大小
stShareStack_t* share_stack; //配置設定的共享棧
stCoRoutineAttr_t()//預設構造函數
{
stack_size = 128 * 1024;
share_stack = NULL;
}
}__attribute__ ((packed));
/*
__attribute__ ((packed)) 的作用就是告訴編譯器取消結構在編譯過程中的優化對齊,按照實際占用位元組
數進行對齊,是GCC特有的文法。(http://blog.chinaunix.net/uid-25768133-id-3485479.html)
*/
struct stCoEpoll_t;//控制定時的結構體 用來管理時間請求
typedef int (*pfn_co_eventloop_t)(void *); //定義一個函數指針 參數類型為一個 void * 傳回值類型為int
typedef void *(*pfn_co_routine_t)( void * );// 基本同上
//2.co_routine
int co_create( stCoRoutine_t **co,const stCoRoutineAttr_t *attr,void *(*routine)(void*),void *arg );
/*
線程create函數,用來建立建立一個線程,注意和線程不同,create隻會建立協程,不會去運作協程。
stCoRoutine_t **co 目前協程 調用函數之後會對co進行指派。
const stCoRoutineAttr_t *attr 使用哪個棧進行配置設定,以及配置設定的大小。傳參不為NULL的話,cIsShareStack會指派true。
void *(*routine)(void*) 協程調用的函數
void *arg 協程調用的函數 使用的參數 類似于線程的用法。
*/
void co_resume( stCoRoutine_t *co );//運作目前的協程,協程加入調用棧中,然後調用co_swap,交換,使程序/線程 運作目前協程
void co_yield( stCoRoutine_t *co );//作用同下
void co_yield_ct();
/*ct = current thread
讓出協程,調用上一個入棧的協程。除非加入事件到時間輪中,不然目前協程不會再次運作。
底層調用co_yield_env。 libco協程是按照調用棧的順序運作的,
是以傳參的co其實是沒用的x co_yield co_yield_ct co_yield_env 作用一樣。
*/
void co_release( stCoRoutine_t *co );//調用co_free 釋放記憶體
stCoRoutine_t *co_self(); //傳回目前協程 其實就是調用棧棧頂的協程。
int co_poll( stCoEpoll_t *ctx,struct pollfd fds[], nfds_t nfds, int timeout_ms );
/*
調用了co_poll_inner
主要的作用為将需要監聽的事件加入時間輪中,并讓出協程。以及在事件觸發後恢複函數執行,清理添加的事件。
stCoEpoll_t *ctx 目前協成,會使用協成中的參數
struct pollfd fds[] 時間數組
nfds_t nfds 數組大小
int timeout_ms 定時時間
*/
void co_eventloop( stCoEpoll_t *ctx,pfn_co_eventloop_t pfn,void *arg );
/*
主要功能為對時間進行輪詢,不斷調用epoll,逾時事件則運作對應的協程。
stCoEpoll_t *ctx 存儲定時事件
pfn_co_eventloop_t pfn,void *arg
if( pfn )
{
if( -1 == pfn( arg ) )
{
break;
}
}
函數中使用這個兩個參數用來檢測是否推出函數,通常為NULL,NULL。
*/
//3.specific
int co_setspecific( pthread_key_t key, const void *value );//設定key對應的value。
void * co_getspecific( pthread_key_t key );//擷取key對應的value
//4.event
stCoEpoll_t * co_get_epoll_ct(); //ct = current thread 擷取環境中存儲定時事件的結構體
//5.hook syscall ( poll/read/write/recv/send/recvfrom/sendto )
void co_enable_hook_sys(); //修改目前協程的cEnableSysHook屬性為true
void co_disable_hook_sys(); //修改目前協程的cEnableSysHook屬性為false
bool co_is_enable_sys_hook(); //查詢目前協程的cEnableSysHook屬性
//6.sync
struct stCoCond_t;//信号量結構體 存儲timewait添加的事件
stCoCond_t *co_cond_alloc();//配置設定記憶體
int co_cond_free( stCoCond_t * cc );//釋放記憶體
int co_cond_signal( stCoCond_t * );//添加最近一次入棧的timedwait事件到活動事件中,co_eventloop輪詢時會運作協程。
int co_cond_broadcast( stCoCond_t * );//廣播 添加所有timewait事件。
int co_cond_timedwait( stCoCond_t *,int timeout_ms );//定時時間添加到epoll中,非定時事件添加到棧中。事件觸發後會删除事件。
//7.share stack
stShareStack_t* co_alloc_sharestack(int iCount, int iStackSize);//配置設定共享棧記憶體
//8.init envlist for hook get/set env
void co_set_env_list( const char *name[],size_t cnt);//初始化環境變量
void co_log_err( const char *fmt,... );//錯誤日志
#endif
個人了解:co_routine.h檔案的作用主要是聲明一些結構體和函數,用于使用庫時調用。後續會介紹協成如何管理,調用棧+時間輪。以及libco的hook,co_swap的實作,友善開發者的閉包實作,個人分析,如有不足,歡迎指出。