Linux Scheduling
有三种调度策略
- SCHED_FIFO,实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃
- SCHED_RR,实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平
- SCHED_OTHER,分时调度策略,不支持优先级使用
SCHED_OTHER
分时调度策略,不支持有限使用,Linux默认采用这种调度策略
SCHED_RR
实时调度策略,支持优先级。
Function
查询并设置调度策略
pthread
库,文件为 <pthread.h>
#include <pthread.h>
#include <sched.h>
static int get_thread_policy(pthread_attr_t *attr)
{
int policy;
int rs = pthread_attr_getschedpolicy(attr, &policy);
switch (policy)
{
case SCHED_FIFO:
printf("policy = SCHED_FIFO\n");
break;
case SCHED_RR:
printf("policy = SCHED_RR\n");
break;
case SCHED_OTHER:
printf("policy = SCHED_OTHER\n");
break;
default:
printf("policy = SCHED_UNKNOW\n");
break;
}
return policy;
}
main(void)
{
pthread_attr_t attr;
int rs;
rs = pthread_attr_init(&attr);
int policy = get_thread_policy(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
policy = get_thread_policy(&attr);
pthread_attr_destroy(&attr);
}
设置优先级
pthread_attr_t attr;
struct sched_param param;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
param.sched_priority = 10;
pthread_attr_setschedparam(&attr, ¶m);
pthread_create(xxx, &attr, xxx, xxx);
pthread_attr_destory(&attr);
Example
#ifdef LINUX_RR_SUPPORT
return _ThreadCreate(thread_name, thread_id, entry_func, arg, stack_size, priority, SCHED_RR, PTHREAD_CREATE_JOINABLE);
#else
return _ThreadCreate(thread_name, thread_id, entry_func, arg, stack_size, priority, SCHED_OTHER,PTHREAD_CREATE_JOINABLE);
#endif
static int32_t _ThreadCreate(const char *thread_name, handle_t *thread_id,
void(*entry_func)(void *), void *arg,
uint32_t stack_size,
uint32_t priority,
uint32_t sched_policy,
uint32_t detach_state)
{
int return_code = 0;
pthread_attr_t custom_attr ;
struct sched_param priority_holder ;
int32_t ret = 0;
uint32_t local_stack_size;
ThreadRecord* thread_rec;
#ifdef ASSERT_DEBUG
assert(thread_id);
assert(entry_func);
assert(priority <= MAX_PRIORITY);
#endif
thread_exit();
/* Check for NULL pointers */
if( entry_func == NULL || thread_id == NULL)
return INVALID_POINTER;
/* Check for bad priority */
if (priority > MAX_PRIORITY)
return INVALID_PRIORITY;
thread_rec = THREAD_NEW();
if (thread_rec == NULL)
return ERR_NO_FREE_IDS;
/* Set stack size */
if (pthread_attr_init(&custom_attr)) {
printf("pthread_attr_init error in ThreadCreate, Pthread ID = %u\n", thread_rec->handle);
goto err;
}
local_stack_size = stack_size <= PTHREAD_STACK_MIN ? PTHREAD_STACK_MIN : stack_size;
if (pthread_attr_setstacksize(&custom_attr, (size_t)local_stack_size)) {
printf("pthread_attr_setstacksize error in ThreadCreate, Pthread ID = %u\n", thread_rec->handle);
goto err;
}
if (sched_policy == SCHED_RR) {
/* Set priority */
if (UpUserPermissions() != true) {
printf("upuserpermissions err in ThreadCreate, Pthread ID = %u\n", thread_rec->handle);
goto err;
}
pthread_attr_setschedpolicy(&custom_attr, SCHED_RR);
ret = pthread_attr_setinheritsched(&custom_attr, PTHREAD_EXPLICIT_SCHED);
if(ret != 0)
{
printf("pthread_attr_setinheritsched error in ThreadCreate, Pthread ID = %u\n", thread_rec->handle);
DownUserPermissions();
goto err;
}
priority_holder.sched_priority = sched_get_priority_max(SCHED_RR) - priority;
ret = pthread_attr_setschedparam(&custom_attr, &priority_holder);
if(ret != 0) {
printf("pthread_attr_setschedparam error in ThreadCreate, Pthread ID = %u\n", thread_rec->handle);
DownUserPermissions();
goto err;
}
DownUserPermissions();
}
if (detach_state == PTHREAD_CREATE_DETACHED) {
ret = pthread_attr_setdetachstate(&custom_attr, PTHREAD_CREATE_DETACHED);
if (ret != 0) {
printf("pthread_attr_setdetachstate failed !\n");
goto err;
}
}
/* Create thread */
thread_rec->entry_func = entry_func;
thread_rec->arg = arg;
thread_rec->status = JOINABLE;
if (UpUserPermissions() != true) {
printf("upuserpermissions err in ThreadCreate, Pthread ID = %u\n", thread_rec->handle);
goto err;
}
return_code = pthread_create(&(thread_rec->id), &custom_attr, default_thread_function, thread_rec);
if (return_code != 0) {
printf("pthread_create error in ThreadCreate, Pthread ID = %u\n", thread_rec->handle);
DownUserPermissions();
goto err;
}
DownUserPermissions();
//*thread_id = thread_rec->handle;
*thread_id = thread_rec->handle;
//id_to_handle[thread_rec->handle] = thread_rec->id;
/* this Id no longer free */
thread_rec->stack_size = stack_size;
thread_rec->priority = priority;
return_code = pthread_attr_getstack(&custom_attr, &thread_rec->stack_base, &thread_rec->stack_size);
if (return_code != 0) {
printf("%s: pthread_attr_getstack err: %d", __func__, return_code);
return ERROR;
}
pthread_attr_destroy(&custom_attr);
return SUCCESS;
err:
if (thread_rec->freed == 1)
THREAD_FREE(thread_rec);
pthread_attr_destroy(&custom_attr);
return ERROR;
}