1. Linux內核的三種調度策略
- SCHED_OTHER 分時調度策略
- SCHED_FIFO 實時調度策略,先到先服務。一旦占用cpu則一直運行。一直運行直到有更高優先級任務到達或自己放棄
- SCHED_RR 實時調度策略,時間片輪轉。當進程的時間片用完,系統將重新分配時間片,並置於就緒隊列尾。放在隊列尾保證了所有具有相同優先級的RR任務的調度公平。
2. 線程的調度策略相關 API
系統創建線程時,默認是 SCHED_OTHER。如果我們要改變線程的調度策略的話,可以通過下面的這個函數實現。
#include <pthread.h>
//set/get scheduling policy attribute in thread attributes object
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
//attr: 線程屬性的結構體指針
//policy: SCHED_FIFO, SCHED_RR, and SCHED_OTHER
3. 當前調度策略支持的優先級范圍 API
#include <sched.h>
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);
/*
Supported policy values are SCHED_FIFO, SCHED_RR, SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, and SCHED_DEAD‐LINE. Further details about these policies can be found in sched(7).
Processes with numerically higher priority values are scheduled before processes with numerically lower priority values.
Thus, the value returned by sched_get_priority_max() will be greater than the value returned by sched_get_priority_min().
Linux allows the static priority range 1 to 99 for the SCHED_FIFO and SCHED_RR policies, and the priority 0 for the remain‐ing policies. Scheduling priority ranges for the various policies are not alterable.
數字越大,線程的優先級越高。
對於SCHED_FIFO and SCHED_RR policies,優先級數字是 1 - 99
其它調度策略的優先級一直為0
*/
4. 線程優先級設置 API
#include <pthread.h>
//set/get scheduling parameter attributes in thread attributes object
int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
//Compile and link with -pthread.
//Scheduling parameters are maintained in the following structure:
struct sched_param {
int sched_priority; /* Scheduling priority */
};
5.測試代碼
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>
int get_thread_sched_policy(const pthread_attr_t *attr)
{
int sched_policy;
int ret = pthread_attr_getschedpolicy(attr, &sched_policy);
assert(ret == 0);
switch (sched_policy)
{
case SCHED_FIFO:
printf("sched_policy = SCHED_FIFO\n");
break;
case SCHED_RR:
printf("sched_policy = SCHED_RR\n");
break;
case SCHED_OTHER:
printf("sched_policy = SCHED_OTHER\n");
break;
default:
break;
}
return sched_policy;
}
int set_thread_sched_policy(pthread_attr_t *attr, const int policy)
{
int ret = pthread_attr_setschedpolicy(attr, policy);
assert(ret == 0);
return ret;
}
int get_sched_policy_prior_max(const int policy)
{
int ret = sched_get_priority_max(policy);
assert(ret != -1);
return ret;
}
int get_sched_policy_prior_min(const int policy)
{
int ret = sched_get_priority_min(policy);
assert(ret != -1);
return ret;
}
int get_thread_priority(const pthread_attr_t *attr, int *priority)
{
struct sched_param param;
int ret = pthread_attr_getschedparam(attr, ¶m);
assert(ret == 0);
*priority = param.sched_priority;
return ret;
}
int set_thread_priority(pthread_attr_t *attr, const int priority)
{
struct sched_param param;
param.sched_priority = priority;
int ret = pthread_attr_setschedparam(attr, ¶m);
assert(ret == 0);
}
int main(int argc, char const *argv[])
{
//對線程屬性初始化,初始化完成以后,pthread_attr_t結構體的內容就是OS現在線程的默認屬性
pthread_attr_t attr;
int ret = pthread_attr_init(&attr);
assert(ret == 0);
//獲得當前調度策略
int policy = get_thread_sched_policy(&attr);
//獲取當前調度策略的線程優先級范圍
printf("max priority: %d\n", get_sched_policy_prior_max(policy));
printf("min priority: %d\n", get_sched_policy_prior_min(policy));
//獲取SCHED_FIFO策略的線程優先級范圍
policy = SCHED_FIFO;
printf("max priority: %d\n", get_sched_policy_prior_max(policy));
printf("min priority: %d\n", get_sched_policy_prior_min(policy));
//獲取SCHED_RR策略的線程優先級范圍
policy = SCHED_RR;
printf("max priority: %d\n", get_sched_policy_prior_max(policy));
printf("min priority: %d\n", get_sched_policy_prior_min(policy));
//手動設置調度策略
set_thread_sched_policy(&attr, SCHED_FIFO);
//設置優先級
set_thread_priority(&attr, 5);
//獲取優先級
int priority;
get_thread_priority(&attr, &priority);
printf("priority is %d\n", priority);
//恢復之前的策略
//反初始化pthread_attr_t 結構,如果pthread_attr_init實現的屬性空間是動態分配的,則會釋放該空間
ret = pthread_attr_destroy(&attr);
assert(ret == 0);
return 0;
}
輸出結果
hany@ubuntu:~/lab$ ./pthread_sched_prior
sched_policy = SCHED_OTHER
max priority: 0
min priority: 0
max priority: 99
min priority: 1
max priority: 99
min priority: 1
priority is 5
6.擴展接口
//set/get scheduling policy and parameters of a thread
#include <pthread.h>
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);
int pthread_getschedparam(pthread_t thread, int *restrict policy, struct sched_param *restrict param);
//Compile and link with -pthread.