1、讓出處理器
linux提供乙個系統呼叫執行程序主動讓出執行權:sched_yield。程序執行的好好的,為什麼需要這個函式呢?有一種情況是使用者空間執行緒的鎖定。如果乙個執行緒試圖取得另乙個執行緒所持有的鎖,則新的執行緒應該讓出處理器知道該鎖變為可用。使用者空間鎖沒有核心的支援,這是乙個最間單、最有效率的做法。但是現在linux執行緒實現引入乙個使用futexes的優化解決方案。
另乙個情況是在有處理器密集型程式可用週期性呼叫sched_yield,試圖將該程序對系統的衝擊減到最小。不管怎麼說,如何排程程式應該是系統的事情,而不是程序自己去管。eg:
int main()複製**return
0;}
那該呼叫核心是如何實現的?2.6以前的版本sched_yield所造成的影響非常小,如果存在另乙個可以執行的程序,核心就切換到該程序,把進行呼叫的程序放在可執行程序列表的結尾處。短期內核心會對該程序進行重新排程。這樣的話可能出現「桌球」現象,也就是兩個程式來回執行,直到他們都執行結束。2.6版本中做了一些改變:
如果程序是rr,把它放到可執行程序結尾,返回。
否則,把它從可執行程序列表移除,放到到期程序列表,這樣在其他可執行程序時間片用完之前不會再執行該程序。
從可執行程序列表中找到另乙個要執行的程序。
2、程序的優先順序
看過cfs中會看到程序的nice value會決定程序會執行多長時間,或者說是占用的百分比。可以通過系統呼叫nice來設定、獲取程序的nice value。該值的範圍是-20~19,越低的值越高的優先順序(這個在計算虛擬時間的時候放在分母上),實時程序應該是負數,eg:
int main()複製**
因為ret本來就可以是-1,那麼在判斷是否系統呼叫失敗的時候就要綜合ret和errno。還有兩個系統呼叫可以更靈活地設定,getpriority可以獲得程序組、使用者的任何程序中優先順序最高的。setpriority將所指定的所有程序優先順序設定為prio,eg:
int main()複製**
程序有在處理器上執行的優先順序,也有傳輸資料的優先順序:i/o優先順序。linux有額外的兩個系統呼叫可用顯示設定和取得i/o nice value,但是尚未匯出:
int ioprio_get(int which, int who);複製**int ioprio_set(int which, int who, int ioprio);
3、處理器親和性
linux支援具有多個處理器的單一系統。在smp上,系統要決定每個處理器上要執行那些程式,這裡有兩項挑戰:
排程程式必須想辦法充分利用所有的處理器。
切換程式執行的處理器是需要代價的。
程序會繼承父程序的處理器親和性,linux提供兩個系統呼叫用於獲取和設定「硬親和性」。eg:
int main()複製**cpu_zero(&set);
cpu_set(0, &set);
cpu_clr(1, &set);
ret = sched_setaffinity(0, sizeof(cpu_set_t), &set);
if(ret == -1)
printf("
呼叫失敗!\n
"); for(i = 0; i < 10; i++)
return
0;}
4、linux的排程策略與優先順序
關於linux系統中對程序的幾種排程方法和他們的區別就不在這裡說了,這裡關注的是如何獲取、設定這些值。可以使用sched_getscheduler來獲取程序的排程策略,eg:
int main()複製**return
0;}
sched_getparam和sched_setparam介面可用於取得、設定乙個已經設定好的策略,這裡不只是返回乙個策略的id,eg:
int main()複製**
linux提供兩個用於取得有效優先值的範圍的系統呼叫,分別返回最大值、最小值,eg:
int main()複製**
關於時間片,這個概念可能在linux中和傳統的在作業系統的課程中學到的還是有很大的區別的,如果感興趣的化可以看看cfs裡面的。通過sched_rr_get_interval可以取到分配給pid的時間片的長度,eg:
int main()複製**
5、實時程序的預防措施
由於實時程序的本質,開發者在開發和除錯此類程式時應該謹慎行事,如果乙個實時程序突然發脾氣,系統的反應會突然變慢。任何乙個cpu密集型迴圈在乙個實時程式中會繼續無止境地執行下去,只要沒有優先順序更高實時程序變成可執行的。因此設計實時程式的時候要謹慎,這類程式至高無上,可用輕易託跨整個系統,下面是一些要決與注意事項:
因為實時程序會好用系統上一切資源,小心不要讓系統其他程序等不到處理時間。
迴圈可能會一直執行到結束。
小心忙碌等待,也就是實時程序等待乙個優先順序低的程序所占有的資源。
開發乙個實時程序的時候,讓乙個終端保持開啟狀態,以更高的優先順序來執行該實時程序,發生緊急情況終端機依然會有反應,允許你終止失控的實時程序。
使用chrt設定、取得實時屬性。
6、資源限制
linux對程序加上了若干資源限制,這些限制是乙個程序所能耗用的核心資源的上限。限制的型別如下:
rlimit_as:位址空間上限。
rlimit_core:core檔案大小上限。
rlimit_cpu:可耗用cpu時間上限。
rlimit_data:資料段與堆的上限。
rlimit_fsize:所能建立檔案的大小上限。
rlimit_locks:檔案鎖數目上限。
rlimit_memlock:不具備cap_sys_ipc能力的程序最多將多少個位元組鎖進記憶體。
rlimit_msgqueue:可以在訊息佇列中分配多少位元組。
rlimit_nice:最多可以將自己的友善值調多低。
rlimit_nofile:檔案描述符數目的上限。
rlimit_nproc:使用者在系統上能執行程序數目上限。
rlimit_rss:記憶體中頁面的數目的上線。
rlimit_rtprio:不具備cap_sys_nice能力程序所能請求的實時優先順序的上限。
rlimit_sigpending:在佇列中訊號量的上限,linux特有的限制。
rlimit_stack:堆疊大小的上限。
這些就不多說了,到了實際用到的時候再仔細看,eg:
int main()
併發控制 sched yield 函式
include int sched yield void sched yield讓出cpu後,並不一定會執行另乙個程序,可能依然是執行該執行緒,而sleep一定會等待一段時間,sched yield函式可以使用另乙個級別等於或高於當前執行緒的執行緒先執行。如果沒有符合條件的執行緒,那麼這個函式將會立...
sched yield 函式 高階程序管理
1 讓出處理器 linux提供乙個系統呼叫執行程序主動讓出執行權 sched yield。程序執行的好好的,為什麼需要這個函式呢?有一種情況是使用者空間執行緒的鎖定。如果乙個執行緒試圖取得另乙個執行緒所持有的鎖,則新的執行緒應該讓出處理器知道該鎖變為可用。使用者空間鎖沒有核心的支援,這是乙個最間單 ...
sched yield 函式 高階程序管理
1 讓出處理器 linux提供乙個系統呼叫執行程序主動讓出執行權 sched yield。程序執行的好好的,為什麼需要這個函式呢?有一種情況是使用者空間執行緒的鎖定。如果乙個執行緒試圖取得另乙個執行緒所持有的鎖,則新的執行緒應該讓出處理器知道該鎖變為可用。使用者空間鎖沒有核心的支援,這是乙個最間單 ...