You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单核心支持多少线程?4核多线程程序不同调度策略并发数咨询

4核系统中不同调度策略线程的并发运行数量解析及代码优化建议

咱们先把核心问题拆解清楚,再给你针对性的代码修改建议:

一、三种调度策略的并发运行上限

你对SCHED_FIFO的判断完全正确,咱们逐个说:

1. SCHED_FIFO(实时先来先服务)

作为实时调度策略,它的优先级高于所有非实时线程。在4核机器上,同一优先级的SCHED_FIFO线程最多同时运行4个——每个物理核心同一时间只能承载一个线程,同优先级的FIFO线程会按“先来先服务”的顺序占用核心,一旦拿到CPU就会一直运行,直到主动放弃(比如调用sched_yield())或者被更高优先级的实时线程抢占。如果你创建超过4个同优先级FIFO线程,剩下的会进入等待队列,等核心空闲后再执行。

2. SCHED_RR(实时时间片轮转)

同样是实时调度策略,优先级和SCHED_FIFO处于同一层级(都高于非实时)。它和FIFO的核心区别是:同优先级的RR线程会按固定时间片轮流占用CPU。但从“同时运行”的角度看,同一优先级的SCHED_RR线程最大并发数还是4个——毕竟物理核心只有4个,时间片轮转只是让同优先级线程交替使用核心,但同一时刻每个核心只能跑一个线程。如果创建8个同优先级RR线程,它们会分成4组交替运行,总耗时会接近单个线程的2倍(因为每个线程只能分到一半的CPU时间)。

3. SCHED_OTHER(普通CFS调度)

这是Linux默认的非实时调度策略,采用完全公平调度(CFS)算法。从“真正并发运行”的角度来说,它的上限也是4个——物理核心数决定了同一时刻能跑的线程数。不过CFS会通过时间片轮转让多个线程“看起来”同时运行,比如你创建8个SCHED_OTHER线程,系统会给每个线程分配CPU时间片,交替执行,但同一时刻还是只有4个线程在真正跑。另外要注意:只要有实时线程(FIFO/RR)在运行,SCHED_OTHER线程会被抢占,只有当所有实时线程都处于等待状态时,普通线程才能获得CPU时间。

二、针对测试需求的代码修改建议

你的代码是用来测试线程完成延迟任务的耗时,咱们可以调整代码来验证上面的结论,核心修改点如下:

1. 新增调度策略设置函数

实时调度策略需要特权(root权限)才能设置,所以要给每个线程指定调度策略和优先级:

#include <pthread.h>
#include <sched.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <sys/resource.h>
#include <string.h>

// 线程数据结构,存ID、调度策略等信息
typedef struct {
    int id;
    int policy;
    int priority; // 实时策略用,SCHED_OTHER忽略
    int nice;     // SCHED_OTHER用
} ThreadData;

// 设置线程调度策略
int set_thread_sched(pthread_t thread, int policy, int priority, int nice) {
    struct sched_param param;
    memset(&param, 0, sizeof(param));
    param.sched_priority = priority;
    
    // 设置实时调度策略
    if (policy == SCHED_FIFO || policy == SCHED_RR) {
        if (pthread_setschedparam(thread, policy, &param) != 0) {
            perror("Failed to set real-time scheduler");
            return -1;
        }
    } 
    // 设置SCHED_OTHER的nice值
    else if (policy == SCHED_OTHER) {
        if (setpriority(PRIO_PROCESS, 0, nice) != 0) {
            perror("Failed to set nice value");
            return -1;
        }
    }
    return 0;
}

2. 修改线程任务函数,记录核心ID和耗时

让每个线程记录自己运行的核心、开始/结束时间,方便你观察并发情况:

void *thread_task(void *arg) {
    ThreadData *data = (ThreadData *)arg;
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    // 执行足够长的耗时任务,避免被快速调度走
    for (long i = 0; i < 1000000000; i++) {
        __asm__ __volatile__("nop"); // 空操作,防止编译器优化掉循环
    }
    
    clock_gettime(CLOCK_MONOTONIC, &end);
    long long elapsed = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec);
    int cpu = sched_getcpu(); // 获取当前运行的核心ID
    
    const char *policy_name;
    switch(data->policy) {
        case SCHED_FIFO: policy_name = "SCHED_FIFO"; break;
        case SCHED_RR: policy_name = "SCHED_RR"; break;
        case SCHED_OTHER: policy_name = "SCHED_OTHER"; break;
        default: policy_name = "UNKNOWN";
    }
    
    printf("Thread %d | Policy: %s | CPU: %d | Elapsed: %.2f ms\n", 
           data->id, policy_name, cpu, elapsed / 1000000.0);
    
    pthread_exit(NULL);
}

3. 主函数批量创建线程测试

你可以分批次测试:先单独测试FIFO,再测试RR,最后测试SCHED_OTHER,也可以混合测试抢占情况:

int main() {
    const int THREAD_COUNT = 8; // 测试超过核心数的线程
    pthread_t threads[THREAD_COUNT];
    ThreadData thread_data[THREAD_COUNT];
    
    // 示例:创建8个SCHED_FIFO线程(优先级设为50)
    for (int i = 0; i < THREAD_COUNT; i++) {
        thread_data[i].id = i;
        thread_data[i].policy = SCHED_FIFO;
        thread_data[i].priority = 50;
        thread_data[i].nice = 0;
        
        if (pthread_create(&threads[i], NULL, thread_task, &thread_data[i]) != 0) {
            perror("Failed to create thread");
            return 1;
        }
        
        // 设置调度策略
        set_thread_sched(threads[i], SCHED_FIFO, 50, 0);
    }
    
    // 等待所有线程完成
    for (int i = 0; i < THREAD_COUNT; i++) {
        pthread_join(threads[i], NULL);
    }
    
    return 0;
}

4. 测试注意事项

  • 必须用root权限运行程序,否则无法设置实时调度策略;
  • 如果要测试SCHED_OTHER,把policy改成SCHED_OTHER,调整nice值即可;
  • 观察输出:如果是FIFO/RR线程,前4个线程的耗时会接近(并行运行),后4个的耗时会是前4个的总和左右(等待核心空闲);SCHED_OTHER的8个线程耗时会接近单个线程的2倍(因为时间片轮转,每个线程分到一半CPU时间)。

内容的提问来源于stack exchange,提问作者Lazarus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:31:56