Linux thread scheduling and priority setting

Source: Internet
Author: User

Reprint: http://blog.csdn.net/a_ran/article/details/43759729

Three scheduling strategies for the Linux kernel:

1,sched_other time-sharing scheduling strategy,
2,sched_fifo Real-time scheduling strategy, first-come-first service. Runs continuously once the CPU is occupied. Keep running until a higher priority task arrives or abandons itself

3,SCHED_RR Real Time scheduling strategy, time slice rotation. When the time slice of the process is exhausted, the system will redistribute the time slices and place them at the end of the ready queue. Placed at the end of the queue ensures that all RR tasks with the same priority are scheduled for a fair Linux thread priority setting
First, the following two functions can be used to get the highest and lowest priority that a thread can set, and the policy in the function is the macro definition of the above three strategies:

int Sched_get_priority_max (int policy);

int sched_get_priority_min (int policy);

Sched_other is not supported for priority use, while SCHED_FIFO and SCHED_RR support priority use, they are 1 and 99 respectively, the higher the value the higher the priority.
Set and get priority through the following two functions

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);
 param.sched_priority = 51; //设置优先级

   系统创建线程时,默认的线程是SCHED_OTHER。所以如果我们要改变线程的调度策略的话,可以通过下面的这个函数实现。

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

The above Param uses the following data structure:

struct sched_param
{
    int __sched_priority; //所要设定的线程优先级
};

We can use the following test procedure to illustrate the priority of our own system support:

#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

static int Get_thread_policy (pthread_attr_t *attr)
{
int policy;
int rs = Pthread_attr_getschedpolicy (Attr,&policy);
ASSERT (rs==0);
Switch (Policy)
{
Case SCHED_FIFO:
printf ("policy= sched_fifo\n");
Break
Case SCHED_RR:
printf ("policy= sched_rr");
Break
Case Sched_other:
printf ("policy=sched_other\n");
Break
Default
printf ("policy=unknown\n");
Break
}
Return policy;
}

static void Show_thread_priority (pthread_attr_t *attr,int policy)
{
int priority = Sched_get_priority_max (policy);
ASSERT (Priority!=-1);
printf ("max_priority=%d\n", priority);
priority= sched_get_priority_min (Policy);
ASSERT (Priority!=-1);
printf ("min_priority=%d\n", priority);
}

static int get_thread_priority (pthread_attr_t *attr)
{
struct Sched_param param;
int rs = Pthread_attr_getschedparam (Attr,&param);
ASSERT (rs==0);
printf ("priority=%d", param.__sched_priority);
return param.__sched_priority;
}

static void Set_thread_policy (pthread_attr_t *attr,int policy)
{
int rs = Pthread_attr_setschedpolicy (Attr,policy);
ASSERT (rs==0);
Get_thread_policy (attr);
}

int main (void)
{
pthread_attr_t attr;
struct Sched_param sched;
int RS;
rs = Pthread_attr_init (&attr);
ASSERT (rs==0);

int policy = Get_thread_policy (&attr);
printf ("Show Current configuration of priority\n");
Show_thread_priority (&attr,policy);
printf ("Show Sched_fifo of priority\n");
Show_thread_priority (&AMP;ATTR,SCHED_FIFO);
printf ("Show sched_rr of priority\n");
Show_thread_priority (&AMP;ATTR,SCHED_RR);
printf ("Show priority of the current thread\n");
int priority = Get_thread_priority (&attr);

printf ("Set thread policy\n");
printf ("Set Sched_fifo policy\n");
Set_thread_policy (&AMP;ATTR,SCHED_FIFO);
printf ("Set SCHED_RR policy\n");
Set_thread_policy (&AMP;ATTR,SCHED_RR);
printf ("Restore current policy\n");
Set_thread_policy (&attr,policy);

rs = Pthread_attr_destroy (&attr);
ASSERT (rs==0);
return 0;
}

Here is the result of the test program running:

policy=sched_other
Show current configuration of priority
Max_priority=0
min_priority=0
Show Sched_fifo of the priority
Max_ priority=99
Min_priority=1
Show sched_rr of priority
Max_priority=99
Min_priority=1
Show priority of Current thread
Priority=0set thread policy
Set sched_fifo policy
Policy= sched_fifo
Set &NBSP;SCHED_RR Policy
Policy= sched_rrrestore current policy
Policy=sched_other

Here's a test of two of these features, Sched_other and SCHED_RR, and the question of priority, is not guaranteed, high-priority threads, can be guaranteed to run first.
The following test program creates three threads, the default created thread's scheduling policy is sched_other, and the remaining two threads of the scheduling policy are set to SCHED_RR. The kernel version of my Linux is 2.6.31. SCHED_RR is based on time slices to determine the scheduling of threads. Time slices run out, no matter how high the priority of this thread is not running, but into the ready queue, waiting for the next time slice to arrive, then how long will this time slice last? In the seventh chapter of "in-depth understanding of Linux kernel" process scheduling, this is the case, Linux takes a single empirical approach, that is, to choose the longest possible, while maintaining a good time for the time slice. Here also does not give a specific time, may be based on different CPUs, and there is a multi-CPU situation.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

void Thread1 ()
{
Sleep (1);
int i,j;
int policy;
struct Sched_param param;
Pthread_getschedparam (Pthread_self (), &policy,&param);
if (policy = = Sched_other)
printf ("sched_other\n");
if (policy = = SCHED_RR);
printf ("Sched_rr 1 \ n");
if (POLICY==SCHED_FIFO)
printf ("sched_fifo\n");

for (i=1;i<10;i++)
{
for (j=1;j<5000000;j++)
{
}
printf ("Thread 1\n");
}
printf ("Pthread 1 exit\n");
}

void Thread2 ()
{
Sleep (1);
int i,j,m;
int policy;
struct Sched_param param;
Pthread_getschedparam (Pthread_self (), &policy,&param);
if (policy = = Sched_other)
printf ("sched_other\n");
if (policy = = SCHED_RR);
printf ("sched_rr\n");
if (POLICY==SCHED_FIFO)
printf ("sched_fifo\n");

for (i=1;i<10;i++)
{
for (j=1;j<5000000;j++)
{

}
printf ("Thread 2\n");
}
printf ("Pthread 2 exit\n");
}

void Thread3 ()
{
Sleep (1);
int i,j;
int policy;
struct Sched_param param;
Pthread_getschedparam (Pthread_self (), &policy,&param);
if (policy = = Sched_other)
printf ("sched_other\n");
if (policy = = SCHED_RR)
printf ("SCHED_RR \ n");
if (POLICY==SCHED_FIFO)
printf ("sched_fifo\n");

for (i=1;i<10;i++)
{
for (j=1;j<5000000;j++)
{
}
printf ("Thread 3\n");
}
printf ("Pthread 3 exit\n");
}

int main ()
{
int i;
i = Getuid ();
if (i==0)
printf ("The current user is root\n");
Else
printf ("The current user was not root\n");

pthread_t ppid1,ppid2,ppid3;
struct Sched_param param;

pthread_attr_t attr,attr1,attr2;

Pthread_attr_init (&AMP;ATTR1);
Pthread_attr_init (&AMP;ATTR);
Pthread_attr_init (&AMP;ATTR2);
 param.sched_priority = 51;
 pthread_attr_setschedpolicy(&attr2,SCHED_RR);
 pthread_attr_setschedparam(&attr2,&param);
 pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);//要使优先级其作用必须要有这句话

 param.sched_priority = 21;
 pthread_attr_setschedpolicy(&attr1,SCHED_RR);
 pthread_attr_setschedparam(&attr1,&param);
 pthread_attr_setinheritsched(&attr1,PTHREAD_EXPLICIT_SCHED);
 
 pthread_create(&ppid3,&attr,(void *)Thread3,NULL);
 pthread_create(&ppid2,&attr1,(void *)Thread2,NULL);
 pthread_create(&ppid1,&attr2,(void *)Thread1,NULL);
 
 pthread_join(ppid3,NULL);
 pthread_join(ppid2,NULL);
 pthread_join(ppid1,NULL);
 pthread_attr_destroy(&attr2);
 pthread_attr_destroy(&attr1);
 return 0;
}

The following is the result of running one of the programs:

sudo ./prio_ Test
The current user is root
sched_other
sched_rr
sched_rr 1 
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
Thread 1
Pthread 1 exit
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Thread 2
Pthread 2 exit
Thread 3
Thread 3
Thread 3
Thread 3
Thread 3
Thread 3
Thread 3
Thread 3
Thread 3
Pthread 3 exit

    Here we can see that because the scheduling policy for thread 3 is sched_other, and the scheduling policy for thread 2 is SCHED_RR, in Thread3, Thread 3 is preempted by thread 1 and thread 2. Because thread 1 has a priority greater than thread 2, threads 1 runs ahead of thread 2, but there is a portion of thread 2 running before thread 1.
    I thought, as long as the priority of the thread is high, will be run first, in fact, this understanding is one-sided, especially in the SMP of the PC will increase its uncertainty.
    In fact, the normal process of scheduling, is the CPU based on the process priority to calculate the time slice, this does not necessarily guarantee that the high-priority process must first run, but compared with the lower priority process, usually higher priority processes get more CPU time slice. In fact, if you want to ensure that one thread runs out of another thread, it is necessary to use multi-threaded synchronization techniques, semaphores, condition variables, and so on. Instead of absolutely relying on the priority level, to ensure.
    However, from the results of the run, we can see that the scheduling policy is SCHED_RR thread 1, thread 2 does preempt the scheduling policy to Sched_other thread 3. This is understandable, since SCHER_RR is a real-time scheduling strategy.
   Real-time processes are replaced by another process only when one of the following events occurs. The
  (1) process is preempted by another real-time process with a higher real-time priority. The
  (2) process performs a blocking operation and goes to sleep
  (3) The process stops (in the task_stopped or task_traced state) or is killed. The
  (4) process voluntarily abandons the CPU by invoking the system call Sched_yield (). The
  (5) process is based on the realtime process of the time slice rotation (SCHED_RR), and the time slice is exhausted. The real-time process of the
   based on the temporal rotation is that it does not really change the priority of the process, but rather changes the length of the basic time slice of the process. Therefore, the process scheduling based on time-slice rotation does not guarantee that the high-priority process will run first.
   The following is another run result:

sudo ./prio_test
The current user is root
SCHED_OTHER
SCHED_RR 1 
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
thread 1
Pthread 1 exit
SCHED_RR
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
thread 2
Pthread 2 exit
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
thread 3
Pthread 3 exit

It can be seen that not every time a high-priority thread is guaranteed to run first.

Linux thread scheduling and priority setting

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.