執行緒輪詢阻塞,由系統排程喚醒,實時性不高。
執行緒阻塞的方式好多,不過根本原因是呼叫能引起排程的函式即可,其他的工作就讓系統排程來完成。
readthread最簡單的就是使用sleep函式讓執行緒進入休眠。等休眠結束後,執行緒由「阻塞狀態」進入「就緒狀態」,期間就需要系統根據不同執行緒間的nice值來評判執行的優先順序。顯然這種方式的實時性不高,而且還可能被系統中斷打斷的可能。不過對於我們而言,這種狀態已經足夠了。因為現在的系統都是微秒級別,基本差別不到差別。而且對於使用這種方式的使用者,也不需要很高的實時性要求。足夠我們使用了。}
再次說到,核心空間的用法跟使用者空間很相似。這種使用方法,在核心也有相應的辦法實現的,除了像上面的使用方法外,核心還可以借助schedule的系統排程來完成,這種方式直接使用系統排程,更為簡潔。而且對於開乙個排程和開一線程,對於核心而言,原理性都是一樣的。所以在核心裡面的做法,是建議使用schedule的方式,而且有需要的話,還可以使用schedule_work_on和schedule_delayed_owrk_on來指定執行的cpu,資源由我們自動分配。
首先說明一下,在linux編寫多執行緒程式需要包含標頭檔案pthread.h。也就是說你在任何採用多執行緒設計的程式中都會看到類似這樣的**:#include
當然,進包含乙個標頭檔案是不能搞定執行緒的,還需要連線libpthread.so這個庫,因此在程式連線階段應該有類似這樣的指令:
gcc program.o
-o program -lpthread
標頭檔案: 原型: pthread_t pthread_self();返回值: 返**用執行緒的執行緒id.
二、執行緒建立
在執行中建立乙個執行緒, 可以為該執行緒分配它需要做的工作(執行緒執行函式), 該執行緒共享程序的資源. 建立執行緒的函式pthread_create()
標頭檔案:
原型:
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(start_rtn)(void), void *restrict arg);
返回值: 成功則返回0, 否則返回錯誤編號.
引數:tidp: 指向新建立執行緒id的變數, 作為函式的輸出.
attr: 用於定製各種不同的執行緒屬性, null為預設屬性(見下).
start_rtn: 函式指標, 為執行緒開始執行的函式名.該函式可以返回乙個void *型別的返回值,而這個返回值也可以是其他型別,並由 pthread_join()獲取
arg: 函式的唯一無型別(
void
)指標引數, 如要傳多個引數, 可以用結構封裝.
linux下多執行緒程式的編譯方法:
因為pthread的庫不是linux系統的庫,所以在進行編譯的時候要加上 -lpthread
# gcc filename -lpthread //
預設情況下gcc使用c庫,要使用額外的庫要這樣選擇使用的庫
執行緒的合併與分離我們首先要明確的乙個問題就是什麼是執行緒的合併。從前面的敘述中讀者們已經了解到了,pthread_create()介面負責建立了乙個執行緒。
那麼執行緒也屬於系統的資源,這跟記憶體沒什麼兩樣,而且執行緒本身也要佔據一定的記憶體空間。
眾所周知的乙個問題就是c或c++程式設計中如果要通過malloc()或new分配了一塊記憶體,就必須使用free()或delete來**這塊記憶體,否則就會產生著名的記憶體洩漏問題。
既然執行緒和記憶體沒什麼兩樣,那麼有建立就必須得有**,否則就會產生另外乙個著名的資源洩漏問題,這同樣也是乙個嚴重的問題。那麼執行緒的合併就是**執行緒資源了。
執行緒的合併是一種主動**執行緒資源的方案。當乙個程序或執行緒呼叫了針對其它執行緒的pthread_join()介面,就是執行緒合併了。
這個介面會阻塞呼叫程序或執行緒,直到被合併的執行緒結束為止。當被合併執行緒結束,pthread_join()介面就會**這個執行緒的資源,並將這個執行緒的返回值返回給合併者。
與執行緒合併相對應的另外一種執行緒資源**機制是執行緒分離,呼叫介面是pthread_detach()。
執行緒分離是將執行緒資源的**工作交由系統自動來完成,也就是說當被分離的執行緒結束之後,系統會自動**它的資源。
因為執行緒分離是啟動系統的自動**機制,那麼程式也就無法獲得被分離執行緒的返回值,這就使得pthread_detach()介面只要擁有乙個引數就行了,那就是被分離執行緒控制代碼。
執行緒合併和執行緒分離都是用於**執行緒資源的,可以根據不同的業務場景酌情使用。不管有什麼理由,你都必須選擇其中一種,否則就會引發資源洩漏的問題,這個問題與記憶體洩漏同樣可怕。
功能:呼叫執行緒終止同程序中,其他的執行緒,呼叫該方法後,被終止的執行緒並不一定立馬被終止,只有在下次系統呼叫或呼叫了pthread_testcancel()方法後,才真正終止執行緒。建立執行緒#include#include取消執行緒#include
#include
#include
#include
char message[50] = "
thread_test";
void* thread_func(void *arg);
intmain()
printf(
"wait for the thread!\n");
pthread_join(t_thread, &thread_result);
printf(
"執行緒已結束,返回值為%s\n
", (char*)thread_result);
printf(
"message的值為%s\n
", message);
free
(thread_result);
exit(exit_success);
}void* thread_func(void *arg)
#include#include#include
#include
#include
void *thread_func(void *arg)
if((res = pthread_setcanceltype(pthread_cancel_deferred, null)) != 0
) printf(
"子執行緒正在執行!\n");
for(int i = 0; i < 10; i++)
pthread_exit(exit_success);
}int
main()
sleep(3);
printf(
"取消執行緒!\n");
if((res = pthread_cancel(thread)) != 0
) exit(exit_success);
}
多執行緒實現輪詢列印資料
如圖 要列印數字1 100,讓三個執行緒列印,實現 public class printdemo public void setnum int num public intgetindex public void setindex int index static class waits exten...
redis實現輪詢演算法 實現乙個簡單的輪詢演算法
前言 負載均衡,大家應該聽的也不少了,也實踐過n次了。當然也會知道,負載均衡是有不少演算法的 隨機,輪詢,加權輪詢,最少連線。本文重點說的是輪詢。先舉個例子看看輪詢演算法是如何運作的。假設我們的api站點有3臺負載 10.0.10.1,10.0.10.2和10.0.10.3 客戶端第一次請求api的...
新增裝置輪詢操作
private ifacilityservice facilitysrva servicelocator.get private ifacilityservice facilitysrvb servicelocator.get 需要生成兩個 類實體,不然同乙個 類實體的,兩次呼叫會是按序列化方式進行...