POSIX執行緒 (六)

2021-08-24 18:27:56 字數 4802 閱讀 4011

執行緒屬性-排程

下面我們來看一下我們也許希望改變的第二個執行緒屬性:排程。改變排程屬性與設定分離屬性相類似,但是我們可以使用另外兩個函式來查詢可用的等級級別,sched_get_priority_max與sched_get_priority_min。

試驗--排程

因為thread6.c是與前面的例子十分類似,這裡我們只看一下其中的區別。

1 首先,我們需要一些額外的變數:

int max_priority;

int min_priority;

struct sched_param scheduling_value;

2 在我們設定分離屬性之後,我們設定排程策略。

res = pthread_attr_setschedpolicy(&thread_attr, sched_other);

if (res != 0)

3 接下來我們檢視允許級別的範圍:

max_priority = sched_get_priority_max(sched_other);

min_priority = sched_get_priority_min(sched_other);

4 並且設定乙個級別:

scheduling_value.sched_priority = min_priority;

res = pthread_attr_setschedparam(&thread_attr, &scheduling_value);

if (res != 0)

工作原理

這個例子與設定分離狀態屬性相類似,所不同的是我們設定排程策略。

關閉執行緒

有時我們希望乙個執行緒可以請求另乙個執行緒結束,而不是向其傳送乙個訊號。執行緒有乙個方法可以完成這個任務,而且並行使用訊號處理,執行緒具有乙個在他們被請求結束時修改其行為的方法。

首先我們來看一下請求執行緒結束的函式:

#include

int pthread_cancel(pthread_t thread);

這個函式宣告很顯示:給定乙個執行緒識別符號,我們可以請求其關閉。在收到關閉請求之後,事情有一些複雜,但是並不是很多。乙個執行緒可以使用pthread_setcancelstate來設定其關閉狀態。

#include

int pthread_setcancelstate(int state, int *oldstate);

第乙個引數或者為pthread_cancel_enable,這個引數允許執行緒接收關閉請求,或者是pthread_cancel_disable,這個引數會使得函式忽略關閉請求。oldstate指標允許獲取前乙個狀態。如果我們對這個狀態不感興趣,我們可以簡單的傳遞乙個null。如果接受了關閉請求,執行緒可以採用乙個第二級控制,關閉型別,這是由pthread_setcanceltype來設定的。

#include

int pthread_setcanceltype(int type, int *oldtype);

這個型別的值可以為pthread_cancel_asynchronous,這個型別可以在接收到關閉請求後立即執行,或者為pthread_cancel_deferred,這個型別會使得關閉請求等待直到執行下列函式中的乙個:pthread_join,pthread_cond_wait,pthread_cond_timedwait,pthread_testcancel,sem_wait或者是sigwait。

在這一章我們並沒有看到這些函式,因為並不是所有的函式都需要。如以前的一樣,更為詳細的資訊可以在手冊中檢視。

再一次說明,oldtype允許獲取前乙個狀態,如果我們對前乙個狀態不感興趣,我們可以傳遞乙個null。預設情況下,執行緒以關閉狀態pthread_cancel_enable與關閉狀態pthread_cancel_deferred開始。

試驗--關閉執行緒

我們這裡的程式thread7.c是由thread1.c發展來的。這一次,主線程向其所建立的執行緒傳送乙個關閉請求。

#include

#include

#include

#include

#include

void *thread_function(void *arg);

int main()

sleep(3);

printf("canceling thread...\n");

res = pthread_cancel(a_thread);

if(res != 0)

printf("waiting for thread to finish...\n");

res = pthread_join(a_thread,&thread_result);

if(res != 0)

exit(exit_success);

}void *thread_function(void *arg)

res = pthread_setcanceltype(pthread_cancel_deferred,null);

if(res != 0)

printf("thread_function is running\n");

for(i=0;i<10;i++)

pthread_exit(0);

}工作原理

在用通常的方法建立乙個新執行緒之後,主線程休眠(允許新執行緒啟動)並且傳送乙個關閉請求。

sleep(3);

printf("canceling thread...\n");

res = pthread_cancel(a_thread);

if(res != 0)

在所建立的執行緒中,我們首先設定關閉狀態允許關閉。

res = pthread_setcancelstate(pthread_cancel_enable,null);

if(res != 0)

然後我們設定關閉型別。

res = pthread_setcanceltype(pthread_cancel_deferred,null);

if(res != 0)

最後執行緒等待關閉。

for(i=0;i<10;i++)

多執行緒

直到現在,我們總是使得程式的乙個執行執行緒只建立乙個執行緒。然而,我們不希望使得大家認為我們只能建立乙個執行緒。

試驗--多執行緒

作為我們本章的最後乙個例子,thread8.c,我們演示如何在同乙個程式中建立多個執行緒,並且以他們啟動的不同順序來收集這些執行緒。

#include

#include

#include

#include

#include

#define num_threads 6

void *thread_function(void *arg);

int main()

sleep(1);

}printf("waiting for threads to finish...\n");

for(lots_of_threads = num_threads -1;lots_of_threads >=0;lots_of_threads--)

else

}printf("all done\n");

exit(exit_success);

}void *thread_function(void *arg)

當我們執行這個程式時,我們會得到下面的輸出:

$ ./thread8

thread_function is running. argument

thread_function is running. argument

thread_function is running. argument

thread_function is running. argument

thread_function is running. argument

bye from 1

thread_function is running. argument

waiting for threads to finish...

bye from 5

picked up a thread

bye from 0

bye from 2

bye from 3

bye from 4

picked up a thread

picked up a thread

picked up a thread

picked up a thread

picked up a thread

all done

正如我們所看到的,我們建立了多個執行緒,並且允許他們以亂序結束 。在這個程式中存在乙個bug,如果我們由啟動執行緒的迴圈中移除sleep呼叫就會得到驗證。我們包含就要演示當我們使用執行緒編寫程式時需要小心。可以定位嗎?我們會在下面的"工作原理"部分進行解釋。

工作原理

在這一章,我們了解了如何在乙個程序內部建立多個執行執行緒,而其中每個執行緒共享檔案域變數。然後我們**了執行緒控制對臨界**與資料的訪問方法,使用訊號量與互斥。在此之後,我們討論了執行緒屬性的控制,而且討論了我們如何將他們與主線程分離,從而他不再等待他所建立的執行緒結束。在快速了解了執行緒如何請求另乙個執行緒完成與接收執行緒如何管理這些請求之後,我們提供了乙個多個並行執行緒執行的例子。

我們並沒有足夠的空間來討論每乙個函式呼叫與相關的執行緒,但是我們現在應具有足夠的知識來使用執行緒編寫我們的程式,並且可以通過閱讀手冊頁來**更多的執行緒知識。

POSIX執行緒 (六)

執行緒屬性 排程 下面我們來看一下我們也許希望改變的第二個執行緒屬性 排程。改變排程屬性與設定分離屬性相類似,但是我們可以使用另外兩個函式來查詢可用的等級級別,sched get priority max與sched get priority min。試驗 排程 因為thread6.c是與前面的例子...

POSIX執行緒 (六)

執行緒屬性 排程 下面我們來看一下我們也許希望改變的第二個執行緒屬性 排程。改變排程屬性與設定分離屬性相類似,但是我們可以使用另外兩個函式來查詢可用的等級級別,sched get priority max與sched get priority min。試驗 排程 因為thread6.c是與前面的例子...

POSIX執行緒 (六)

執行緒屬性 排程 下面我們來看一下我們也許希望改變的第二個執行緒屬性 排程。改變排程屬性與設定分離屬性相類似,但是我們可以使用另外兩個函式來查詢可用的等級級別,sched get priority max與sched get priority min。試驗 排程 因為thread6.c是與前面的例子...