面试题答案
一键面试SCHED_OTHER调度策略
- 设置线程优先级方式:SCHED_OTHER是Linux系统默认的调度策略,它不支持用户设置传统意义上的优先级(基于nice值进行调度,但范围有限且并非传统优先级概念)。nice值范围是 -20(最高优先级)到19(最低优先级),可通过
nice
命令或setpriority
函数设置。例如,使用setpriority(PRIO_PROCESS, 0, -5)
可将当前进程的nice值设为 -5 。 - 对线程执行顺序和资源分配的影响:它采用时间片轮转算法进行调度,线程会轮流使用CPU资源。但由于其不依赖传统优先级概念,优先级对执行顺序影响较小,主要根据时间片分配CPU,各线程获得相对公平的CPU时间。
SCHED_FIFO调度策略
- 设置线程优先级方式:通过
pthread_setschedparam
函数来设置线程优先级,其优先级范围是0到sched_get_priority_max(SCHED_FIFO)
。例如:
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
void* thread_function(void* arg) {
printf("Thread running\n");
return NULL;
}
int main() {
pthread_t thread;
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_create(&thread, NULL, thread_function, NULL);
pthread_setschedparam(thread, SCHED_FIFO, ¶m);
pthread_join(thread, NULL);
return 0;
}
- 对线程执行顺序和资源分配的影响:该调度策略下,具有最高优先级的线程会一直运行,直到它主动放弃CPU(比如调用
pthread_yield
、进行I/O操作或被更高优先级线程抢占)。如果多个线程优先级相同,则按照FIFO(先进先出)顺序执行。资源分配会优先满足高优先级线程,低优先级线程可能长时间得不到执行机会。
SCHED_RR调度策略
- 设置线程优先级方式:同样通过
pthread_setschedparam
函数设置,优先级范围与SCHED_FIFO相同。例如:
#include <pthread.h>
#include <sched.h>
#include <stdio.h>
void* thread_function(void* arg) {
printf("Thread running\n");
return NULL;
}
int main() {
pthread_t thread;
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_create(&thread, NULL, thread_function, NULL);
pthread_setschedparam(thread, SCHED_RR, ¶m);
pthread_join(thread, NULL);
return 0;
}
- 对线程执行顺序和资源分配的影响:SCHED_RR也是基于优先级调度,但与SCHED_FIFO不同的是,相同优先级的线程采用时间片轮转方式执行。高优先级线程依然优先执行,但在时间片用完后,会将CPU让给同优先级的其他线程。这样在一定程度上保证了相同优先级线程间的公平性,同时也突出了高优先级线程的优先性。
不同调度策略下线程执行顺序变化场景
假设有三个线程T1、T2、T3,优先级分别为高、中、低。
- SCHED_OTHER调度策略:线程执行顺序主要依据时间片轮转,优先级影响不大,所以三个线程可能会交替执行,相对公平地获取CPU时间。
- SCHED_FIFO调度策略:T1(高优先级)会一直运行,直到主动放弃CPU,然后T2(中优先级)才会执行,T2执行完或放弃CPU后T3(低优先级)才会执行。
- SCHED_RR调度策略:T1(高优先级)先执行,时间片用完后,如果T2(中优先级)和T3(低优先级)也准备好运行,T1会将CPU让给T2,T2执行完自己的时间片后,如果T3准备好则T3执行,之后又回到T1执行,如此循环。