zoukankan      html  css  js  c++  java
  • 实时和非实时调度策略测试总结

    创建两个线程,用不同的实时调度(SCHED_FIFO,SCHED_RR)和非实时调度(SCHED_OTHER)策略,总结如下:

    • 用root身份运行,才能设置实时调度策略。否则,
      • 创建默认线程后,调用pthread_setschedparam()设置实时调用策略失败。
      • 创建带实时调度策略的attr参数的线程无法运行。
    • 同为实时调度线程,不论是SCHED_RR还是SCHED_FIFO,高优先级线程都能对低优先级线程实施抢占,且在主动放弃CPU之前不会释放占用。
    • 相同优先级的实时调度线程,
      • 如果同为SCHED_RR线程,线程之间分享时间片,轮转运行。
      • 如果同为SCHED_FIFO线程,其中之一(谁先运行)会一直运行直到到其主动释放占用CPU,另一个才会执行。即同优先级不会分享时间片。
      • 如果两个分别为SCHED_RR,SCHED_FIFO线程,SCHED_RR线程会分享时间片,即时间片用完后会放弃占用CPU,被SCHED_FIFO线程占用。但SCHED_FIFO线程占用后不会和SCHED_RR线程分享时间片,会一直运行到其主动释放占用后,SCHED_RR线程才会再次执行。
    • 两个线程一个为实时调用线程,一个为非实时调用线程,实时线程不论是何优先级(>0),何种调度方式,都能对非实时线程实施抢占,且不会对非实时线程共享时间片。
    • 同为非实时调度线程,setpriority()(root才能设置)设置其nice值(-20~19,越小优先级越高),影响调度器分配的时间片nice为19时,当有其他更高优先级nice的线程在运行时,系统给nice19的线程分配的时间片相当少,甚至没有。
    • 实时线程并且优先级为最高99时,系统会显示(top,ps命令等)该线程为rt。
    • 绑定CPU对线程效率(不论是实时还是非实时调度线程)有提高,因为线程在不同核心上切换有消耗。
    #include <sys/time.h>
    #include <sys/resource.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #define __USE_GNU
    #include <pthread.h>
    #include <sched.h>
    
    long long a = 0;
    long long b = 0;
    
    int attach_cpu(int cpu_index)
    {
        int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
        if (cpu_index < 0 || cpu_index >= cpu_num) {
            printf("cpu index ERROR!
    ");
            return -1;
        }
        
        cpu_set_t mask;
        CPU_ZERO(&mask);
        CPU_SET(cpu_index, &mask);
        
        if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
            printf("set affinity np ERROR!
    ");
            return -1;
        }
        
        return 0;
    }
    
    
    void *thread1(void *param)
    {
        printf("t1 tid %d
    ", gettid());
        /*if (setpriority(PRIO_PROCESS, 0, 19) != 0)
        {
            printf("setpriority failed!
    ");
        }*/
        attach_cpu(0);
        
        long long i;
        for (i = 0; i < 10000000000; i++)
        {
            a++;
        }
    }
    
    void *thread2(void *param)
    {
        printf("t2 tid %d
    ", gettid());
        if (setpriority(PRIO_PROCESS, 0, -20) != 0)
        {
            printf("setpriority failed!
    ");
        }
        attach_cpu(0);
        long long i;
        for (i = 0; i < 10000000000; i++)
        {
            b++;
        }
    }
    
    
    //#define C_SET
    
    int main()
    {
        pthread_t t1;
        pthread_t t2;
    
    #ifdef C_SET
        pthread_attr_t attr;
    #else
        int policy;
    #endif
        struct sched_param param;
    
    #ifdef C_SET
        if (pthread_attr_init(&attr) != 0) {
            printf("pthread_attr_init failed!
    ");
            return -1;
        }
        if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) {
            printf("pthread_attr_setinheritsched failed!
    ");
        }
        if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) {
            printf("pthread_attr_setschedpolicy failed!
    ");
        }
        param.sched_priority = 10;
        if (pthread_attr_setschedparam(&attr, &param) != 0) {
            printf("pthread_attr_setschedparam failed!
    ");
        }
        
        if (pthread_create(&t1, &attr, thread1, NULL) != 0)
    #else
        if (pthread_create(&t1, NULL, thread1, NULL) != 0)
    #endif
        {
            printf("create t1 failed!
    ");
            return -1;
        }
    
    #ifndef C_SET
        param.sched_priority = 1;
        policy = SCHED_FIFO;
        if (pthread_setschedparam(t1, policy, &param) != 0) {
            printf("set t1 sched param failed!
    ");
        }
    #endif
    
        sleep(1);
    
    #ifdef C_SET
        param.sched_priority = 10;
        if (pthread_attr_setschedparam(&attr, &param) != 0) {
            printf("pthread_attr_setschedparam failed!
    ");
        }
        if (pthread_create(&t2, &attr, thread2, NULL) != 0)
    #else
        if (pthread_create(&t2, NULL, thread2, NULL) != 0)
    #endif
        {
            printf("create t2 failed!
    ");
            return -1;
        }
    
    #ifndef C_SET
        param.sched_priority = 99;
        policy = SCHED_FIFO;
    /*    if (pthread_setschedparam(t2, policy, &param) != 0) {
            printf("set t2 sched param failed!
    ");
        }*/
    #endif
    
        while (a != 10000000000 || b != 10000000000)
        {
            printf("a=%lld, b=%lld
    ", a, b);
            sleep(1);
        }
        printf("a=%lld, b=%lld
    ", a, b);
    
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);
    
        return 0;
    }
    测试代码

    以上是在x86的ubuntu系统的测试结果,在Android上的测试结果类似,因为都是linux内核。在Android上没有pthread_setaffinity_np(),需要用syscall系统调用。

    syscall(__NR_sched_setaffinity, gettid(), sizeof(mask), &mask);

     参考:

    https://blog.csdn.net/maray/article/details/2900689

    https://www.cnblogs.com/wanpengcoder/p/11767185.html

    http://man7.org/linux/man-pages/man7/sched.7.html

  • 相关阅读:
    NYOJ 1073 最大值 (模拟)
    NYOJ 1063 生活的烦恼 (二叉树)
    NYOJ 1022 合纵连横 (并查集)
    [leetcode-553-Optimal Division]
    [leetcode-496-Next Greater Element I]
    [leetcode-556-Next Greater Element III]
    [leetcode-500-Keyboard Row]
    [leetcode-36-Valid Sudoku]
    [leetcode-127-Word Ladder]
    [leetcode-567-Permutation in String]
  • 原文地址:https://www.cnblogs.com/mightycode/p/13930352.html
Copyright © 2011-2022 走看看