溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

基于linuxthreads2.0.1線程如何進行源碼分析join.c

發(fā)布時間:2021-12-09 09:35:12 來源:億速云 閱讀:158 作者:柒染 欄目:大數(shù)據(jù)

基于linuxthreads2.0.1線程如何進行源碼分析join.c,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

join.c文件一共有三個函數(shù),下面我們一個個看一下。

1 pthread_exit

基于linuxthreads2.0.1線程如何進行源碼分析join.c

   
     
 
    
    

// 線程退出
void pthread_exit(void * retval)
{
 // 獲取當前線程的結構體
 pthread_t self = thread_self();
 pthread_t joining;
 struct pthread_request request;

 /* Reset the cancellation flag to avoid looping if the cleanup handlers
    contain cancellation points */
 // 設置成0,避免其他函數(shù)里判斷是cancel狀態(tài),然后再調(diào)pthread_exit函數(shù)
 self->p_canceled = 0;
 /* Call cleanup functions and destroy the thread-specific data */
 // 執(zhí)行clean節(jié)點的函數(shù)
 __pthread_perform_cleanup();
 // 遍歷pthread_keys數(shù)組,銷毀線程中的specifics數(shù)據(jù)
 __pthread_destroy_specifics();
 /* Store return value */
 // 加鎖
 acquire(&self->p_spinlock);
 // 退出值,可以在join中返回給其他線程
 self->p_retval = retval;
 /* Say that we've terminated */
 // 已終止
 self->p_terminated = 1;
 /* See if someone is joining on us */
 // 判斷有沒有其他線程在等待該線程退出
 joining = self->p_joining;
 release(&self->p_spinlock);
 /* Restart joining thread if any */
 // 喚醒他
 if (joining != NULL) restart(joining);
 /* If this is the initial thread, block until all threads have terminated.
    If another thread calls exit, we'll be terminated from our signal
    handler. */
 // 如果是主線程退出,通知manage線程,如果是一般線程則直接執(zhí)行exit退出
 if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
   request.req_thread = self;
   request.req_kind = REQ_MAIN_THREAD_EXIT;
   // 寫入管道
   __libc_write(__pthread_manager_request, (char *)&request, sizeof(request));
   // 掛起等待喚醒,全部子線程都退出后了才喚醒主線程,然后主線程也退出,見manager.c的__pthread_manager函數(shù)
   suspend(self);
 }
 /* Exit the process (but don't flush stdio streams, and don't run
    atexit functions). */
 // 線程退出,見操作系統(tǒng)實現(xiàn)
 _exit(0);
}              

2 pthread_join

基于linuxthreads2.0.1線程如何進行源碼分析join.c

   
     
 
    
    

// 調(diào)用該函數(shù)的線程會等待th線程結束
int pthread_join(pthread_t th, void ** thread_return)
{
 volatile pthread_t self = thread_self();
 struct pthread_request request;
 // 不能等待自己結束,否則會死鎖,即自己無法結束
 if (th == self) return EDEADLK;
 acquire(&th->p_spinlock);
 /* If detached or already joined, error */
 // th線程已經(jīng)是detach狀態(tài),即不是joinable的,或者已經(jīng)被jion過了
 if (th->p_detached || th->p_joining != NULL) {
   release(&th->p_spinlock);
   return EINVAL;
 }
 /* If not terminated yet, suspend ourselves. */
 // join的線程還在運行,則需要等待
 if (! th->p_terminated) {
   // 記錄誰在join th
   th->p_joining = self;
   release(&th->p_spinlock);
   // 掛起等待喚醒,th退出的時候才會喚醒self線程,見pthread_exit的restart
   suspend_with_cancellation(self);
   acquire(&th->p_spinlock);
   /* This is a cancellation point */
   // 取消點
   if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
     th->p_joining = NULL;
     release(&th->p_spinlock);
     pthread_exit(PTHREAD_CANCELED);
   }
 }
 /* Get return value */
 // 線程已經(jīng)結束,設置線程的返回值
 if (thread_return != NULL) *thread_return = th->p_retval;
 release(&th->p_spinlock);
 /* Send notification to thread manager */
 // 管道的寫端,join的線程已經(jīng)退出,通知manage線程回收退出線程的資源,見REQ_FREE的處理
 if (__pthread_manager_request >= 0) {
   // 發(fā)送th線程已經(jīng)結束的通知給manager線程,self是發(fā)送者
   request.req_thread = self;
   request.req_kind = REQ_FREE;
   request.req_args.free.thread = th;
   // 寫入管道
   __libc_write(__pthread_manager_request,
(char *) &request, sizeof(request));
 }
 return 0;
}

             

3 pthread_detach

基于linuxthreads2.0.1線程如何進行源碼分析join.c

   
     
 
    
    

int pthread_detach(pthread_t th)
{
 int terminated;
 struct pthread_request request;

 acquire(&th->p_spinlock);
 /* If already detached, error */
 // detach過了
 if (th->p_detached) {
   release(&th->p_spinlock);
   return EINVAL;
 }
 /* If already joining, don't do anything. */
 // 有線程join了該線程,不能detach
 if (th->p_joining != NULL) {
   release(&th->p_spinlock);
   return 0;
 }
 /* Mark as detached */
 // 標記已經(jīng)detach
 th->p_detached = 1;
 terminated = th->p_terminated;
 release(&th->p_spinlock);
 /* If already terminated, notify thread manager to reclaim resources */
 // 線程已經(jīng)退出了,detach的時候,通知manager,__pthread_manager_request是管道寫端
 if (terminated && __pthread_manager_request >= 0) {
   request.req_thread = thread_self();
   request.req_kind = REQ_FREE;
   request.req_args.free.thread = th;
   __libc_write(__pthread_manager_request,
(char *) &request, sizeof(request));
 }
 return 0;
}  

關于基于linuxthreads2.0.1線程如何進行源碼分析join.c問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業(yè)資訊頻道了解更多相關知識。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI