日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux进程的高级管理,sched_yield()函数 高级进程管理

發布時間:2024/3/26 linux 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux进程的高级管理,sched_yield()函数 高级进程管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、讓出處理器

Linux提供一個系統調用運行進程主動讓出執行權:sched_yield。進程運行的好好的,為什么需要這個函數呢?有一種情況是用戶空間線程的鎖定。如果一個線程試圖取得另一個線程所持有的鎖,則新的線程應該讓出處理器知道該鎖變為可用。用戶空間鎖沒有內核的支持,這是一個最間單、最有效率的做法。但是現在Linux線程實現引入一個使用futexes的優化解決方案。

另一個情況是在有處理器密集型程序可用周期性調用sched_yield,試圖將該進程對系統的沖擊減到最小。不管怎么說,如何調度程序應該是系統的事情,而不是進程自己去管。eg:

int main(){ int ret, i;

ret = sched_yield(); if(ret == -1){

printf("調用sched_yield失敗!\n");

} return 0;

}

那該調用內核是如何實現的?2.6以前的版本sched_yield所造成的影響非常小,如果存在另一個可以運行的進程,內核就切換到該進程,把進行調用的進程放在可運行進程列表的結尾處。短期內內核會對該進程進行重新調度。這樣的話可能出現“乒乓球”現象,也就是兩個程序來回運行,直到他們都運行結束。2.6版本中做了一些改變:

如果進程是RR,把它放到可運行進程結尾,返回。

否則,把它從可運行進程列表移除,放到到期進程列表,這樣在其他可運行進程時間片用完之前不會再運行該進程。

從可執行進程列表中找到另一個要執行的進程。

2、進程的優先級

看過CFS中會看到進程的nice value會決定進程會運行多長時間,或者說是占用的百分比。可以通過系統調用nice來設置、獲取進程的nice value。該值的范圍是-20~19,越低的值越高的優先級(這個在計算虛擬時間的時候放在分母上),實時進程應該是負數,eg:

int main(){ int ret, i;

ret = nice(0);

printf("當前進程的nice value:%d\n", ret);

ret = nice(10);

printf("當前進程的nice value:%d\n", ret); return 0;

}

因為ret本來就可以是-1,那么在判斷是否系統調用失敗的時候就要綜合ret和errno。還有兩個系統調用可以更靈活地設置,getpriority可以獲得進程組、用戶的任何進程中優先級最高的。setpriority將所指定的所有進程優先級設置為prio,eg:

int main(){ int ret, i;

ret = getpriority(PRIO_PROCESS, 0);

printf("nice value:%d\n", ret);

ret = setpriority(PRIO_PROCESS, 0, 10);

ret = getpriority(PRIO_PROCESS, 0);

printf("nice value:%d\n", ret); return 0;

}

進程有在處理器上執行的優先級,也有傳輸數據的優先級: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(){ int ret, i;

cpu_set_t set;

CPU_ZERO(&set);

ret = sched_getaffinity(0, sizeof(cpu_set_t), &set); if(ret == -1)

printf("調用失敗!\n"); for(i = 0; i < 10; i++){ int cpu = CPU_ISSET(i, &set);

printf("cpu=%i is %s\n", i, cpu?"set":"unset");

}

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++){ int cpu = CPU_ISSET(i, &set);

printf("cpu=%i is %s\n", i, cpu?"set":"unset");

} return 0;

}

4、Linux的調度策略與優先級

關于Linux系統中對進程的幾種調度方法和他們的區別就不在這里說了,這里關注的是如何獲取、設置這些值。可以使用sched_getscheduler來獲取進程的調度策略,eg:

int main(){ int ret, i; struct sched_param sp;

sp.sched_priority = 1;

ret = sched_setscheduler(0, SCHED_RR, &sp); if(ret == -1)

printf("sched_setscheduler failed.\n"); if(errno == EPERM)

printf("Process don't the ability.\n");

ret = sched_getscheduler(0); switch(ret){ case SCHED_OTHER:

printf("Policy is normal.\n"); break; case SCHED_RR:

printf("Policy is round-robin.\n"); break; case SCHED_FIFO:

printf("Policy is first-in, first-out.\n"); break; case -1:

printf("sched_getscheduler failed.\n"); break; default:

printf("Unknow policy\n");

} return 0;

}

sched_getparam和sched_setparam接口可用于取得、設定一個已經設定好的策略,這里不只是返回一個策略的ID,eg:

int main(){ int ret, i; struct sched_param sp;

sp.sched_priority = 1;

ret = sched_setparam(0, &sp); if(ret == -1)

printf("sched_setparam error.\n");

ret = sched_getparam(0, &sp); if(ret == -1)

printf("sched_getparam error.\n");

printf("our priority is %d.\n", sp.sched_priority); return 0;

}

Linux提供兩個用于取得有效優先值的范圍的系統調用,分別返回最大值、最小值,eg:

int main(){ int ret, i; struct sched_param sp;

ret = sched_get_priority_min(SCHED_RR); if(ret == -1)

printf("sched_get_priority_min error.\n");

printf("The min nice value is %d.\n", ret);

ret = sched_get_priority_max(SCHED_RR); if(ret == -1)

printf("sched_get_priority_max error.\n");

printf("The mmax nice value is %d.\n", ret); return 0;

}

關于時間片,這個概念可能在Linux中和傳統的在操作系統的課程中學到的還是有很大的區別的,如果感興趣的化可以看看CFS里面的。通過sched_rr_get_interval可以取到分配給pid的時間片的長度,eg:

int main(){ int ret, i; struct timespec tp;

ret = sched_rr_get_interval(0, &tp); if(ret == -1)

printf("sched_rr_get_interval error.\n");

printf("The time is %ds:%ldns.\n", (int)tp.tv_sec, tp.tv_nsec); return 0;

}

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(){ int ret, i; struct rlimit rlim;

rlim.rlim_cur = 32*1024*1024;

rlim.rlim_max = RLIM_INFINITY;

ret = setrlimit(RLIMIT_CORE, &rlim);

ret = getrlimit(RLIMIT_CORE, &rlim); if(ret == -1)

printf("getrlimit error.\n");

printf("RLIMIT_CORE limits: soft=%ld hard=%ld\n", rlim.rlim_cur, rlim.rlim_max); return 0;

}

總結

以上是生活随笔為你收集整理的linux进程的高级管理,sched_yield()函数 高级进程管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。