基于linuxthreads2.0.1線程如何進行源碼分析join.c,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
創(chuàng)新互聯(lián)一直通過網(wǎng)站建設(shè)和網(wǎng)站營銷幫助企業(yè)獲得更多客戶資源。 以"深度挖掘,量身打造,注重實效"的一站式服務(wù),以成都網(wǎng)站設(shè)計、成都做網(wǎng)站、移動互聯(lián)產(chǎn)品、全網(wǎng)整合營銷推廣服務(wù)為核心業(yè)務(wù)。10年網(wǎng)站制作的經(jīng)驗,使用新網(wǎng)站建設(shè)技術(shù),全新開發(fā)出的標(biāo)準(zhǔn)網(wǎng)站,不但價格便宜而且實用、靈活,特別適合中小公司網(wǎng)站制作。網(wǎng)站管理系統(tǒng)簡單易用,維護方便,您可以完全操作網(wǎng)站資料,是中小公司快速網(wǎng)站建設(shè)的選擇。
join.c文件一共有三個函數(shù),下面我們一個個看一下。
1 pthread_exit
// 線程退出
void pthread_exit(void * retval)
{
// 獲取當(dāng)前線程的結(jié)構(gòu)體
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 */
// 設(shè)置成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
// 調(diào)用該函數(shù)的線程會等待th線程結(jié)束
int pthread_join(pthread_t th, void ** thread_return)
{
volatile pthread_t self = thread_self();
struct pthread_request request;
// 不能等待自己結(jié)束,否則會死鎖,即自己無法結(jié)束
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)結(jié)束,設(shè)置線程的返回值
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)結(jié)束的通知給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
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 */
// 標(biāo)記已經(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;
}
關(guān)于基于linuxthreads2.0.1線程如何進行源碼分析join.c問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。