co_routine.h分析

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的實現,方便開發者的閉包實現,個人分析,如有不足,歡迎指出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章