|
分類:
Linux Kernel
2009-03-11 17:16
在Linux內(nèi)核
中,completion是一種簡單的同步機(jī)制,標(biāo)志"things may
proceed"。要使用completion,必須在文件中包含<linux/completion.h>,同時(shí)創(chuàng)建一個(gè)類型為
struct completion的變量。這個(gè)變量可以靜態(tài)地聲明和初始化:
DECLARE_COMPLETION(my_comp); 或者動(dòng)態(tài)初始化: struct completion my_comp; init_completion(&my_comp); 如果驅(qū)動(dòng)程序要在執(zhí)行后面操作之前等待某個(gè)過程的完成,它可以調(diào)用wait_for_completion ,以要完成的事件為參數(shù): void wait_for_completion(struct completion *comp); 如果其它部分代碼可以確定事件已經(jīng)完成,可以調(diào)用下面兩個(gè)函數(shù)之一來喚醒等待該事件的進(jìn)程: void complete(struct completion *comp); void complete_all(struct completion *comp); /* Linux 2.5.x以上版本 */ 前一個(gè)函數(shù)將只喚醒一個(gè)等待進(jìn)程,而后一個(gè)函數(shù)喚醒等待該事件的所以進(jìn)程。由于completion的實(shí)現(xiàn)方式,即使complete在wait_for_competion之前調(diào)用,也可以正常工作。 例如,在MD設(shè)備驅(qū)動(dòng)程序?qū)崿F(xiàn)中,有一個(gè)恢復(fù)線程md_recovery_thread。驅(qū)動(dòng)程序通過md_register_thread和md_unregister_thread來注冊(cè)和注銷恢復(fù)線程。恢復(fù)線程的執(zhí)行邏輯在md_thread函數(shù)中,大致如下: int md_thread(void * arg) { 線程初始化; while (運(yùn)行) { 處理邏輯; 接收信號(hào); } return 0; } md_register_thread將創(chuàng)建一個(gè)恢復(fù)線程,它必須在線程真正初始化結(jié)束之后才能返回該線程的指針。因此,其邏輯是: mdk_thread_t *md_register_thread(void (*run) (void *), void *data, const char *name) { mdk_thread_t *thread; …… struct completion event; /* 為線程分配空間 */ thread = (mdk_thread_t *) kmalloc (sizeof(mdk_thread_t), GFP_KERNEL); …… init_completion(&event); …… thread->event = &event; /* 創(chuàng)建內(nèi)核線程 */ ret = kernel_thread(md_thread, thread, 0); /* 等待線程初始化結(jié)束 */ …… wait_for_completion(&event); /* 返回線程指針 */ return thread; } 而md_unregister_thread通過向線程發(fā)送SIGKILL信號(hào)注銷恢復(fù)線程,它也需要在線程真正退出后才能釋放線程所占用的內(nèi)存。因此,其邏輯是: void md_unregister_thread(mdk_thread_t *thread) { struct completion event; init_completion(&event); thread->event = &event; …… /* 向線程發(fā)送SIGKILL信號(hào)終止其運(yùn)行 */ md_interrupt_thread(thread); /* 等待線程退出 */ wait_for_completion(&event); /* 釋放線程所占用的內(nèi)存 */ kfree(thread); } 如果考慮completion,md_thread的邏輯是: int md_thread(void * arg) { 線程初始化; complete(thread->event); while (運(yùn)行) { 處理邏輯; 接收信號(hào); } complete(thread->event); return 0; } 需要說明的是,由于等待事件是在驅(qū)動(dòng)程序和恢復(fù)線程中的一個(gè)共享資源,它必須是一個(gè)全局變量,或者如實(shí)現(xiàn)代碼中,定義為一個(gè)局部變量,而將其指針放在恢復(fù)線程結(jié)構(gòu)中。 typedef struct mdk_thread_s { …… struct completion *event; …… } mdk_thread_t; |
|
|