?? 2.html
字號:
pthread_t tid; /* 線程號 */<br>oskit_u32_tflags; /* 線程狀態標志 */<br>pthread_lock_t lock; /* 鎖*/<br>queue_chain_t chain; /* 隊列鏈 */<br>int preempt; /*線程優先級 */<br>/*以下用于對死鎖的處理*/<br>pthread_mutex_t mutex; /* 互斥位(死鎖保護)*/<br>pthread_cond_t cond; /* 等待死鎖標志=1 */<br>int dead; /*死鎖了 */<br>/*例子所用到的資源*/<br>int cputime; /* 占用CPU的時間 */<br>intcpticks; /* 上一秒所占的節拍數 */<br>oskit_u32_t pctcpu; /* CPU的占用率*/<br>int childtime; /* 子線程所占用的CPU的開銷*/<br>/*發送信息所用的變量*/<br>pthread_lock_t waitlock; /* 等待鎖*/<br>oskit_u32_twaitflags; /* 等待標志位 */<br>pthread_cond_t *waitcond; /* 等待條件變量*/<br>struct osenv_sleeprec *sleeprec; /*一個osenv_sleep中的線程*/<br>/*以下是進程通訊要用到的*/<br>void *msg; /* 指向要發送的消息的指針*/<br>oskit_size_t msg_size; /* 消息的大小 */<br>pthread_t tid; /*線程號 */<br>void *reply; /* 指向響應信息的指針*/<br>oskit_size_t reply_size; /* 響應內容的大小*/<br>queue_head_t senders; /* 發送隊列中的發送者 */<br>queue_chain_tsenders_chain; /* 發送隊列指針 */<br>/* 以下是所用到的時鐘 */<br>structoskit_timer *condtimer;<br>/* 線程的休眠和喚醒是用一個單獨的計時器實現的 */<br>structoskit_timer *sleeptimer;<br>/* 以下是所用到的信號 */<br>pthread_lock_t siglock; /*保護鎖信號 */<br>sigset_t sigmask; /* 阻塞信號*/<br>sigset_t sigpending; /* 未決信號 */<br>sigset_t sigwaiting; /*等待信號的信號 */<br>oskit_u32_t eip; /* 頁處理故障信號 */<br>/* 鍵值通常是一個固定的隊列*/<br>void *keyvalues[PTHREAD_KEYS_MAX]; /* 鍵值 */<br>/* 以下用于清除操作*/<br>pthread_cleanup_t *cleanups; /* 清楚操作鏈*/<br>char cancelstate; /* 取消狀態 */<br>char canceltype; /*取消類型 */<br>/* 以下是單獨用于調度的鎖*/<br>pthread_lock_t schedlock;<br>void *rtai_priv;<br>intpolicy; /* 調度策略 */<br>int priority; /* 當前的優先級 */<br>structscheduler_entry *scheduler; /* 調度程序入口 */<br>int policy; /* 調度策略*/<br>int priority; /* 當前優先級 */<br>int base_priority; /*初始優先級 */<br>int ticks; /* 調度所省下的節拍*/<br>oskit_timespec_t start; /* 下次運行的時間*/<br>oskit_timespec_t deadline; /* 下次運行的時間*/<br>oskit_timespec_t period; /* 兩次執行見的間隔*/<br>queue_head_t waiters; /* 正在等待的線程 */<br>queue_chain_twaiters_chain; /* 線程隊列鏈 */<br>struct pthread_thread *waiting_for; /* 所等待的線程*/<br>struct pthread_thread *inherits_from; /* 線程從何繼承*/<br>/*以下是CPU的繼承*/<br>struct pthread_thread *scheduler; /* 線程調度程序人口*/<br>schedmsg_t unblockmsg;<br>schedmsg_queue_t *msgqueue;<br>sched_wakecond_t wakeup_cond;/* 喚醒條件 */<br>schedflags_t schedflags; /* 標志 */<br>intdonate_rc; /* 從捐贈線程返回的值 */<br>int timeout; /* 毫秒*/<br>queue_head_t donors; /* 捐贈資源的線程 */<br>queue_chain_tdonors_chain; /* 捐贈隊列鏈 */<br>struct pthread_thread *donating_to; /* 被捐贈的線程*/<br>struct pthread_thread *inherits_from; /* 線程從何繼承 */<br>structpthread_thread *nextup; /* 下一個要執行的線程 */<p><br>2.2 pthreads/pthread_create.c<p>此源碼文件包括了一套完整的線程創建機制,它是全部線程的根源所在,通過閱讀下面的函數分析,將使讀者了解OSKit到底是用什么函數來具體實現線程創建的。我認為在上一節的理論指導下對代碼進行分析,要比泛泛的闡述理論更容易讓讀者接受,更能加深在讀者腦海中的印象。<p>2.2.1 創建線程<br>說明:這就是我們在第一節中提到的創建線程的函數,所有由用戶完成的創建線程的操作,都要調用它來實現。<br>intpthread_create ( pthread_t *tid, const pthread_attr_t *attr,<br>void * (*function )( void * ), void *argument )<br>tid: 指向線程存儲位置的指針<br>attr:指向線程屬性的指針<br>*(*function)(void *): 當線程初始化時所調用的函數<br>*argument: 函數功能<p>2.2.2創建內部線程<br>說明:該函數用于系統核心部分創建核心線程,而一般的用戶沒有調用它的權利,只有系統核心才可以調用。<br>pthread_thread_t*pthread_create_internal ( void * ( *function)( void *), void *argument,constpthread_attr_t *attr)<br>注:內部線程創建時,將阻塞所有的信號<br>sigfillset(pthread->sigmask)<p>2.2.3為主進程創建一個備份線程<br>說明:出于系統安全的原因,OSKit定義了此函數,用于對主線程進行備份。由于線程創建子線程,子線程又創建自己的子線程,如此下去,將產生一個以主線程為根節點的樹形結構,所以一旦主線程丟失,將有可能導致系統崩潰,所以應對其進行備份。<br>pthread_thread_t*pthread_init_mainthread ( pthread_thread_t *pthread )<p>2.2.4初始化創建線程的線程<br>說明:這和UNIX中那個創建進程的進程有些類似,它唯一的工作就是為主線程創建子線程,并且,每個線程都包含一個該線程。<br>pthread_thread_t*thread_init_mainthread ( pthread_thread_t *pthread )<p>2.2.5為等待和休眠的線程創建一個等待時間<br>說明:由于調度的原因,一般線程不可能一直占用CPU,也不可能永遠被掛起,所以OSKit為規定線程的等待時間定義了此函數。<br>voidpthread_prepare_timer ( pthread_thread_t *pthread )<p><br>2.3 pthreads/pthread_attr.c<p>此源碼文件包括了一套完整的線程屬性的初始化機制,它與上一節的線程創建共同作用,規定了線程在創建之初的屬性,通過閱讀下面的函數分析,將使讀者了解OSKit到底是用什么函數來具體實現線程屬性的初始化。<p>2.3.1線程初始化的數據結構<br>說明:系統在創建新線程的時候,會調用此函數來規定被創建線程的屬性,所以此函數在線程屬性機制中站有最主要的地位,是一切線程屬性函數調用的源泉,希望讀者給以充分的重視。<br>intpthread_attr_init ( pthread_attr_t *attr )<br> attr->detachstate =PTHREAD_CREATE_JOINABLE; /* 線程與其他線程關聯*/<br> attr->priority =PRIORITY_NORMAL; /* 線程的優先級 */<br> attr->stacksize = PTHREAD_STACK_MIN; /*線程所占堆棧的 */<br> attr->guardsize = DEFAULT_STACKGUARD; /* 警戒堆棧的大小 */<br> attr->stackaddr = 0; /* 堆棧的大小 */<br> attr->policy = SCHED_RR; /*線程調度類型 */<br> attr->inherit = PTHREAD_EXPLICIT_SCHED; /* 線程繼承類型 */<br> 注:memset 的數據結構 /* \oskit\libc\string\memset.c */<br> void *memset(void *tov, intc, size_t len)<br> { register char *to = tov;<br> while (len-- >0)<br> *to++ = c;<br> return tov;<br> }<br> tov: 指向內存的首地址 c: 分配類型 len:分配長度<p>2.3.2線程屬性的撤銷<br>說明:這個函數是上一個函數的逆操作,在撤銷一個線程的同時,其屬性也應相應地被撤銷,所以OSKit定義了此函數來實現該功能。<br>intpthread_attr_destroy ( pthread_attr_t *attr )<br> memset((void *) attr, -1,sizeof(*attr)); /* 撤銷指針并釋放內存*/<p>2.3.3設置線程的警戒堆棧大小<br>說明:警戒堆棧在操作系統中被廣泛使用,它是源于UNIX的進程間通信,在UNIX系統中,接受進程的消息緩沖可能小于發送進程。所以,當消息到來的時候,為了避免溢出造成的信息丟失,系統創建了警戒堆棧,用來存儲溢出的消息。而OSKit把它用于線程間通信的保護,但用法與UNIX大同小異。<br>intpthread_attr_setguardsize ( pthread_attr_t *attr, size_t guardsize )<p>2.3.4得到警戒堆棧的大小<br>說明:由于OSKit為每個接受線程設置警戒堆棧,所以定義此函數,為的是系統能方便的得到每個接受線程的警戒堆棧的大小,這同樣是出于對安全的考慮。<br>intpthread_attr_getguardsize ( const pthread_attr_t *attr, size_t *guardsize )<p>2.3.5設置線程的分離狀態<br>說明:上邊曾經提到,系統中的線程樹,而線程與線程之間很可能并不是完全獨立的,即使他們處于不同的層次,也可能有一定的相關性或互斥性,所以定義此函數用來規定線程之間的互斥性,即分離狀態是完全有必要的。<br>intpthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate )<p>2.3.6得到線程的分離狀態<br>說明:在規定了分離狀態之后,若A線程要與B線程發生關聯的時候,它必須先看看B線程和其他線程的關系,所以要定義此函數來得到B線程與其他線程的分離狀態,提供給A,然后A在根據具體情況決定是否與B發生關系。<br>intpthread_attr_getdetachstate ( const pthread_attr_t *attr, int *detachstate)<br> *detachstate = attr->detachstate;<p>2.3.7設置線程的繼承關系<br>說明:當線程創建子線程的時候,上邊我提到的那個創建線程的線程會為他們父子之間規定繼承關系,即子線程繼承父線程。<br>intpthread_attr_setinheritsched ( pthread_attr_t *attr, int inheritstate)<br> attr->inherit = inheritstate;<p>2.3.8得到線程的繼承狀態<br>說明:當系統要在復雜的線程樹中得到繼承關系的時,調用此函數便能達到預期的目的。OSKit定義此函數,為的是能在復雜的線程樹中一眼看穿某兩個線程之間的關系。<br>intpthread_attr_getinheritsched ( const pthread_attr_t *attr, int *inheritstate)<br> *inheritstate = attr->inherit;<p>2.3.9設置線程的調度參數<br>說明:OSKit提供了多種線程調度方式供選擇,而且還為每個線程在創建的時候規定了一種調度算法,系統在創建線程的時候調用下面的函數來完成這項工作。<br>intpthread_attr_setschedparam ( pthread_attr_t *attr,const struct sched_param*param )<br> int pri = param->priority;<br> attr->start =param->start; /* 線程開始參數 */<br> attr->period = param->period; /*線程的周期 */<br> attr->deadline = param->deadline; /* 線程運行的最終時限 */<p>2.3.10得到線程調度的參數<br>說明:在OSKit中,每個線程都有其自身的調度方式,換句話說,就是線程的調度方式仿佛是線程的一個屬性,在創建線程的時候就隨線程被規定了,所以調度程序可以通過下面的函數來得到某個線程的調度算法和此時它的優先級。<br>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -