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,¶m); 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 (&ATTR,SCHED_FIFO); printf ("Show sched_rr of priority\n"); Show_thread_priority (&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 (&ATTR,SCHED_FIFO); printf ("Set SCHED_RR policy\n"); Set_thread_policy (&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,¶m); 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,¶m); 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,¶m); 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 (&ATTR1); Pthread_attr_init (&ATTR); Pthread_attr_init (&ATTR2);
param.sched_priority = 51;
pthread_attr_setschedpolicy(&attr2,SCHED_RR); pthread_attr_setschedparam(&attr2,¶m); pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);//要使优先级其作用必须要有这句话
param.sched_priority = 21; pthread_attr_setschedpolicy(&attr1,SCHED_RR); pthread_attr_setschedparam(&attr1,¶m); 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