精华内容
下载资源
问答
  • Linux 线程调度

    2018-07-07 15:29:00
    1.线程sleep()后,会让出cpu的时间片,交由其他线程进行抢占cpu。 线程之间正常的切换是依靠时间片的。 当主线程没有结束,且其在所占有的时间片内,并没有结束自己的工作,此时,子线程将会抢占cpu时间片。 参考...

    1.线程sleep()后,会让出cpu的时间片,交由其他线程进行抢占cpu。

    线程之间正常的切换是依靠时间片的。

    当主线程没有结束,且其在所占有的时间片内,并没有结束自己的工作,此时,子线程将会抢占cpu时间片。

    参考帖子以及下面的评论:https://blog.csdn.net/harry_lyc/article/details/6055734#reply

     

     

    转载于:https://www.cnblogs.com/xuelisheng/p/9277401.html

    展开全文
  • Linux线程调度

    2015-03-17 22:44:10
    由于Linux线程实现的一些特殊性,所以会给我们理解线程及其相关的一些函数带来疑惑,这里做个解答:  1、关于sleep  很多书籍上都说sleep这个系统调用会使整个进程sleep,而不单是sleep一个线程。这样说没...
    由于Linux对线程实现的一些特殊性,所以会给我们理解线程及其相关的一些函数带来疑惑,这里做个解答: 

    1、关于sleep 

    很多书籍上都说sleep这个系统调用会使整个进程sleep,而不单是sleep一个线程。这样说没错,但我们要是在Linux下写一个多线程 的程序,在一个线程中调用sleep,你会发现其他线程照样运行,这是怎么回事呢?这就是由于Linux下的线程,其实线程的注册、销毁等工作是在 pthread库里面,而在内核中,线程其实就是一个进程。Linux对线程的实现是通过__clone调用实现的,这个调用会new多个进程出来,只不 过的是, Linux会设置这些进程的共享内存空间、文件描述符等属性为相同,这样就实现了线程的定义(共享一个进程的内存空间、线程切换不需要切换上下文环 境......)。所以,很多书籍上会说Linux的线程在核内是轻量级的进程,就是这个道理。因为和普通进程相比,Linux的线程在核内就是一些被设 置了很多属性的进程,从而实现了线程。 

    所以,在Linux下,一个线程调用了sleep,反映到核内就是sleep了一个轻量级进程,自然其他的线程(核内的轻量级进程)不受影响,照 样可以run了。简言之,之所以sleep一个线程,其他线程仍然可以执行,这是因为在Linux下,线程和进程不是n对1的,而是1对1的。 

    2、有关线程的调度 

    有了1的描述,我们就清楚的知道了,其实Linux对线程的调度,策略和进程是基本一致的。所以,很多人问,为什么一个线程中如果有一个循环的 话,其他线程都得不到执行,这就是因为Linux对线程的调度,策略和进程是一样的,即,如果一个线程处于一个高密度的工作状态的话,或者该线程的cpu slice没用完的话,这个线程是不会被调度的。有关这个问题,还可以参看本论坛中“有关线程切换的一个问题”一帖。 

    其实说白了,明白了第一点的话,很多Linux线程的问题就迎刃而解了。


    有关Linux下线程的实现方式,再附上一段“POSIX线程编程指南”(来自IBM Developworks)中的描述,这段描述很专业,很到位: 

    我们知道,Linux的线程实现是在核外进行的,核内提供的是创建进程的接口do_fork()。内核提供了两个系统调用__clone()和 fork (),最终都用不同的参数调用do_fork()核内API。当然,要想实现线程,没有核心对多进程(其实是轻量级进程)共享数据段的支持是不行的,因 此,do_fork()提供了很多参数,包括CLONE_VM(共享内存空间)、CLONE_FS(共享文件系统信息)、CLONE_FILES(共享文 件描述符表)、CLONE_SIGHAND(共享信号句柄表)和CLONE_PID(共享进程ID,仅对核内进程,即0号进程有效)。当使用fork系统 调用时,内核调用do_fork()不使用任何共享属性,进程拥有独立的运行环境,而使用pthread_create()来创建线程时,则最终设置了所 有这些属性来调用__clone(),而这些参数又全部传给核内的do_fork(),从而创建的"进程"拥有共享的运行环境,只有栈是独立的,由 __clone()传入。 

    Linux线程在核内是以轻量级进程的形式存在的,拥有独立的进程表项,而所有的创建、同步、删除等操作都在核外 pthread库中进行。pthread库使用一个管理线程(__pthread_manager(),每个进程独立且唯一)来管理线程的创建和终止,为 线程分配线程ID,发送线程相关的信号(比如Cancel),而主线程(pthread_create())的调用者则通过管道将请求信息传给管理线程。
    展开全文
  • Linux 线程调度与优先级 Linux内核的三种调度策略 1,SCHED_OTHER:分时调度策略。 它是默认的线程分时调度策略,所有的线程的优先级别都是0,线程的调度是通过分时来完成的。简单地说,如果系统使用这种调度...

    Linux 线程调度与优先级

    Linux内核的三种调度策略

    1,SCHED_OTHER:分时调度策略。

    它是默认的线程分时调度策略,所有的线程的优先级别都是0,线程的调度是通过分时来完成的。简单地说,如果系统使用这种调度策略,程序将无法设置线程的优先级。请注意,这种调度策略也是抢占式的,当高优先级的线程准备运行的时候,当前线程将被抢占并进入等待队列。这种调度策略仅仅决定线程在可运行线程队列中的具有相同优先级的线程的运行次序。

    2,SCHED_FIFO:实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃。

    它是一种实时的先进先出调用策略,且只能在超级用户下运行。这种调用策略仅仅被使用于优先级大于0的线程。它意味着,使用SCHED_FIFO的可运行线程将一直抢占使用SCHED_OTHER的运行线程J。此外SCHED_FIFO是一个非分时的简单调度策略,当一个线程变成可运行状态,它将被追加到对应优先级队列的尾部。当所有高优先级的线程终止或者阻塞时,它将被运行。对于相同优先级别的线程,按照简单的先进先运行的规则运行。我们考虑一种很坏的情况,如果有若干相同优先级的线程等待执行,然而最早执行的线程无终止或者阻塞动作,那么其他线程是无法执行的,除非当前线程调用如pthread_yield之类的函数,所以在使用SCHED_FIFO的时候要小心处理相同级别线程的动作。

    3,SCHED_RR:实时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平。

    鉴于SCHED_FIFO调度策略的一些缺点,SCHED_RR对SCHED_FIFO做出了一些增强功能。从实质上看,它还是SCHED_FIFO调用策略。它使用最大运行时间来限制当前进程的运行,当运行时间大于等于最大运行时间的时候,当前线程将被切换并放置于相同优先级队列的最后。这样做的好处是其他具有相同级别的线程能在“自私“线程下执行。

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

    int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

    Linux线程优先级设置

    首先,可以通过以下两个函数来获得线程可以设置的最高和最低优先级,函数中的策略即上述三种策略的宏定义:

    int sched_get_priority_max(int policy);
    int sched_get_priority_min(int policy);

    SCHED_OTHER是不支持优先级使用的,而SCHED_FIFO和SCHED_RR支持优先级的使用,他们分别为1和99,数值越大优先级越高。

    设置和获取优先级通过以下两个函数:

    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使用了下面的这个数据结构:

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

    例如:

     param.sched_priority = 51; //设置优先级

    测试程序

    #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\n");
        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\n",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);
    
      //获取默认的线程调度策略
      printf("==    Show current configuration of priority    ==\n");
      int policy = get_thread_policy(&attr);
      show_thread_priority(&attr,policy);
      //打印当前线程的优先级
      printf("show priority of current thread\n");
      int priority = get_thread_priority(&attr);
    
    
       printf("==   Show different Scheduling method priority   ==\n");
      //获取SCHED_FIFO调度策略的最高和最低优先级
      printf("show SCHED_FIFO of priority:\n");
      show_thread_priority(&attr,SCHED_FIFO);
    
     //获取SCHED_RR调度策略的最高和最低优先级
      printf("show SCHED_RR of priority:\n");
      show_thread_priority(&attr,SCHED_RR);
    
      printf("==        Set thread policy        == \n");
      //设置线程的调度属性为SCHED_FIFO
      printf("set SCHED_FIFO policy:\n");  
      set_thread_policy(&attr,SCHED_FIFO);
      priority = get_thread_priority(&attr);
      sched.__sched_priority = 99;
      pthread_attr_setschedparam(&attr,&sched);
      priority = get_thread_priority(&attr);
    
      //设置线程的调度属性为SCHED_FIFO
      printf("set SCHED_RR policy:\n");
      set_thread_policy(&attr,SCHED_RR);
      priority = get_thread_priority(&attr);
      sched.__sched_priority = 55;
      pthread_attr_setschedparam(&attr,&sched);
      priority = get_thread_priority(&attr);
    
      //恢复线程的调度策略
      printf("Restore current policy:\n");
      set_thread_policy(&attr,policy);
    
      rs = pthread_attr_destroy(&attr);
      assert(rs==0);
      return 0;
    }

     

    展开全文
  • Linux 线程调度方式 在创建线程的时候,我们可以指定所要创建线程的属性,属性中有线程的“调度方式”,线程的调度方式有三种: SCHED_OTHER:分时调度策略 根据nice指来确定线程的运行的顺序(counter+20-nice ...

    Linux 线程调度方式

    在创建线程的时候,我们可以指定所要创建线程的属性,属性中有线程的“调度方式”,线程的调度方式有三种:

    • SCHED_OTHER:分时调度策略
      根据nice指来确定线程的运行的顺序(counter+20-nice 值越大,如果当前没有任务在运行,则从就绪队列里找一个这个值最大的线程运行)。nice越小,counter越大。当时间片用完之后或者线程主动交出cpu调度程序才会运行。然后把这个任务放到就绪队列的尾部或者等待队列。重新在就绪队列里找一个(counter+20-nice)最大的线程运行。分时调度策略里是没有优先级的。只有一个类似优先级的概念是(counter+20-nice)。没有优先级,所以没有抢占。

    • SCHED_FIFO:实时调度策略
      先到先服务。一旦占用cpu则一直运行直到有更高优先级任务到达或者自己主动放弃。任务结束后也是放到就绪任务队列的尾部,为了保持相同优先级的任务公平调度。

    • SCHED_RR实时调度策略:

      时间片轮转。从就绪队列里找优先级最高任务执行,当进程时间片用完或者线程主动交出cpu,调度程序才会运行,并置于就绪队列尾或者等待队列中。然后系统在就绪队列里找优先级最高的任务执行。放在对列尾保证了所有具有相同优先级的RR任务的调度公平。

    比较SCHED_FIFO 和 SCHED_RR两种实时调度策略:

    两者唯一的区别在于采取中两种调度策略的线程最大占用cpu时间的长度不同。

    采取SCHED_FIFO调度策略的正在运行的线程释放cpu的情况有:

    • 就绪队列里有更高优先级的线程
    • 当前线程主动释放cpu(等待其他的资源)

    可见,采取SCHED_FIFO调度策略的线程可能会一直占用着cpu。

    采取SCHED_RR调度策略的正在运行的线程释放cpu的情况有:

    • 分配给当前线程的时间片用完了
    • 就绪队列里有更高优先级的线程
    • 当前线程主动释放cpu(等待其他的资源)

    可见,采取SCHED_RR调度策略的线程占用cpu的时间不会超过分配给它的时间片长度。

    展开全文
  • 浅析Linux线程调度

    2017-12-02 13:34:00
    Linux这样实现的线程的好处的之一是:线程调度直接使用进程调度就可以了,没必要再搞一个进程内的线程调度器。在Linux中,调度器是基于线程的调度策略(scheduling policy)和静态调度优先级(s...
  • Linux内核的三种调度策略 SCHED_OTHER 分时调度策略。 它是默认的线程分时调度策略,所有的线程的优先级别都是0,线程调度是通过分时来完成的。简单地说,如果系统使用这种调度策略,程序将无法设置线程的优先级。...
  • 总结:对三种线程调度方式进行测试。 1.SCHED_OTHER:分时调度策略,为默认方式,凡是采用本模式的线程,线程优先级会强制为0,通俗点将,工作在本模式下的线程,都在同一优先级下。所谓的“分时调度策略”,可以...
  • 依赖的是中断机制,通过中断抢回CPU执行权限然后进行调度,如Linux内核对线程调度。 协作式调度。需要主动让出CPU,调用调度代码进行调度,如协程,没有中断机制一般无法真正做到抢占。 Linux NPTL 线程库 看...
  • linux线程调度策略

    千次阅读 2014-04-19 16:48:39
    linux进程调度方法(SCHED_OTHER,SCHED_FIFO,SCHED_RR)  linux内核的三种调度方法: 1,SCHED_OTHER 分时调度策略, 2,SCHED_FIFO实时调度策略,先到先服务 3,SCHED_RR实时调度策略,时间片轮
  • Linux 线程调度与优先级设置

    千次阅读 2017-03-17 18:47:56
    线程调度间的上下文切换 什么是上下文切换? 如果主线程是唯一的线程,那么他基本上不会被调度出去。另一方面,如果可运行的线程数大于CPU的数量,那么操作系统最终会将某个正在运行的线程调度出去,从而 使其他线程...
  • 多线程之linux线程调度策略

    千次阅读 2015-03-21 21:35:40
    linux线程调度策略分为3个:SCHED_OTHER,SCHED_FIFO,SCHED_RR  讲策略之前,大家需要理解实时与非实时之分。实时就是指操作系统对一些中断等的响应时效性非常高,即使是在内核态的时候,非实时反之。目前像...
  • 1.调度策略和优先级 1.1.调度策略 sched.h文件中定义了几种调度策略 /* Scheduling algorithms. */ #define SCHED_OTHER 0 #define SCHED_FIFO 1...通过pthread_create创建,但属性参数传递NULL创建的线程默认以SC...
  • Linux线程调度策略与优先级

    千次阅读 2013-11-25 15:17:45
    Linux内核的三种调度策略:  1,SCHED_OTHER 分时调度策略, 2,SCHED_FIFO实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃 ...Linux线程优先级
  • linux线程调度策略(转)

    千次阅读 2016-06-28 17:38:27
    操作系统通过任务调度算法快速切换线程来模拟多线程并行,交替地停止一个线程,然后切换到另外一个上运行。支持任务优先级,高优先级线程比低优先级线程更先执行,也就是说低优先线程必须等到高

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,889
精华内容 1,555
关键字:

linux线程调度

linux 订阅