2019 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A Lab7
目錄 Contents thread 介紹 Beaglebone thread 範例 Beaglebone 實作 Beaglebone
1-1 thread 介紹 執行緒 (thread) Program 放在二次儲存裝置中,尚沒有被Load到記憶體的一堆Code稱之為「程式」。 Process 已經被Load到記憶體中,任何一行Code隨時會被CPU執行,且其宣告的在記憶體的變數的值會隨著需求而不斷變動。稱之為「程序」。 一個多工作業系統(Multitasking Operating System)可以同時運行多個Process,然而一個CPU一次只能做一件事情,但CPU的數量永遠少於運行中的Process數,因此每個Process使用的時間需要被排程(Scheduling)。 Thread 作業系統能夠進行運算排程的最小單位,被包含在處理序(Process)中,在進代作業系統中,被設計為Process中的實際運作單位。而Thread又由下面兩項組成,Stack(紀錄函數的呼叫路徑,以及這些函數所用到的區域變數)以及目前CPU的狀態。
1-2 thread 介紹 執行緒 (thread) Thread的重點如下: 一個Process可以有多個Thread。 同一個Process內的Thread使用相同的Memory Space,但這些Thread各自擁有其Stack。換句話說,Thread能透過reference存取到相同的object,但是local variable卻是各自獨立的。 現代的作業系統會根據Process的優先權,分別讓各個Process佔據CPU一段時間,以讓各個Process都有機會執行;而Process又會根據Thread的優先權以及已經用掉的CPU時間,在不同的Thread作切換,以讓各個Thread都有機會執行。
thread 範例 2-2 thread 程式碼 gcc thread1.c –lpthread –o thread1
2-1 thread 範例 thread API pthread_create (新增一個 Thread) 標頭檔: #include <pthread.h> 函式宣告: int pthread_create ( pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg ); 傳回值: 傳回 0 代表成功新增,非 0 代表失敗 說明: thread:用來儲存 Thread 的代碼,傳入(pthread_t*)的型態 start_routine:函式指標,指向不定回傳值,不定輸入參數的 Function attr:用來描述 Thread 特性的變數,傳入(pthread_attr_t*)的型態,NULL 代表預設性質 arg:傳入 start_routine 的參入,型態為(void*)
2-1 thread 範例 thread API pthread_join (等待 Thread 執行終止) pthread_exit (結束thread) 標頭檔: 標頭檔: #include <pthread.h> #include <pthread.h> 函式宣告: 函式宣告: int pthread_join ( pthread_t th, void ** thread_return); int pthread_exit ( void * retval); 說明: 說明: th:Thread 的代碼,傳入(pthread_t)的型態,辨別欲等待的 Thread retval:指向傳回值 thread_return:指標的指標因為 Thread 的 Return Type 是(viod*) 傳回值: 傳回 0 代表成功,非 0 代表失敗 傳回值: 傳回 0 代表成功,非 0 代表失敗
異步信號範例 使用signal和`pthread_kill`來終止特定的線程。 可以在線程中使用`pthread_sigmask`來暫時阻止信號。
2-1 thread 範例 thread API sig 函数 pthread_kill 函数 說明: 說明: 標頭檔: 標頭檔: #include <signal.h> #include <signal.h> #include <pthread.h> 函式宣告: 函式宣告: int sigemptyset(sigset_t *set); int sigaddset(sigset_t *set, int signum); int pthread_kill(pthread_t thread, int sig); sigemptyset()用來將參數set信號集初始化並清空。 sigaddset()用來將參數signum代表的信號加入至參數set信號集裡。 向某個線程傳遞一個信號 pthread_t thread:線程號 int sig:信號 傳回值: 傳回值: 執行成功則返回0,如果有錯誤則返回-1。 執行成功則返回0,如果有錯誤則返回-1。
thread 介紹 pthread_kill()函數 該函數其實不是kill線程,而是向線程發送一個signal,向指定ID的線程發送sig信號 第一個參數:要發送信號的線程tid 第二個參數:0是保留信號,用來判斷線程是否還存在,如果int sig的參數不是0,那一定要清楚到底要幹什麼,而且一定要實現線程的信號處理函數,否則,就會影響整個進程。 https://blog.csdn.net/littesss/article/details/71156793 Linux多線程應用中,每個線程可以通過調用 pthread_sigmask() 檢查和更改被阻止的信號。一般情況下,被阻塞的信號將不能中斷此線程的執行。 int pthread_sigmask (int how,const sigset_t *set,sigset_t *oset) 執行函數能夠根據參數如何來實現對信號集的操作,操作主要有三種(how): SIG_BLOCK在進程當前阻塞信號集中添加set指向信號集中的信號, 相當於:mask = mask | set SIG_UNBLOCK如果進程阻塞信號集中包含set指向信號集中的信號,則解除對該信號的阻塞,相當於:mask = mask | ~set SIG_SETMASK更新進程阻塞信號集為set指向的信號集,相當於mask = set
將附件程式碼空白處填上正確的程式碼,並執行結果。 實作 將附件程式碼空白處填上正確的程式碼,並執行結果。 修改線程的屬性 在範例一,我們用pthread_create函數創建了一個線程,在這個線程中,我們使用了默認參數,即將該函數的第二個參數設為NULL。 屬性結構為pthread_attr_t,它同樣在頭檔/usr/include/pthread.h中定義。 屬性值不能直接設置,須使用相關函數進行操作,初始化的函數為pthread_attr_init,這個函數必須在pthread_create函數之前調用。屬性物件主要包括是否綁定、是否分離、堆疊位址、堆疊大小、優先順序。默認的屬性為非綁定、非分離、缺省1M的堆疊、與父進程同樣級別的優先順序。
實作 補充資料: http://zzzaaa12.pixnet.net/blog/post/31958665-%5Bnote%5D-c-thread-programming-in-linux http://blog.xuite.net/tzeng015/twblog/113272158-Linux%E7%B3%BB%E7%B5%B1%E4%B8%8B%E7%9A%84%E5%A4%9A%E7%B7%9A%E7%A8%8B%E7%B7%A8%E7%A8%8B%E5%85%A5%E9%96%80 https://blog.csdn.net/liuguanghui1988/article/details/53607071
Thanks 作業系統實習 Operating Systems