如何理解state_thread库(5)

今天开始探讨st库里的线程调用模型


1)idle_thread;

st库的核心是idle_thread,整个库中,只有调用了底层的分发器dispatch,所有的i/o动作,所有的sleep,都必须汇总到这个函数中来。

首先看初始化伪代码

st_ini()

{

....

new  idle_thread;

int thread stack;

if(setjmp(idle->context))//第一次设置的时候,并不会执行下面的部分。

{

  while(st_active>0)//这个值,在每次调用st_sleep() st_read() st_write()等函数的时,都会+1

{

st_poll_dispatch();//调用底层的epoll等函数,把合适的i/o和时间处理函数放到runq队列中

st_sleep_deal();//检测时间队列中是否有到时的

st_state =RUNABLE;//

if(!setjmp(idle_thread->context))//再次跳转,注意这里的context变化了

{

 find_thread_from_runq()

 else

 set_thread_idle() //这一个if_else,做一个可运行的线程选择。

 longjmp(thread_context);//到最后可以执行的线程中去。

}

}

}

}


上面的代码是我把所有的宏都展开以后的代码。可以看出

1)在idle线程刚创建的时候,是不会被执行的。
2)只有外部调用了驱动函数,比如st_sleep,st_read等驱动函数时,才会执行idle_thread.

3)idle_thread线程的的函数context会变化。首次是在ilde_thread_start的头部,之后就在while循环里面。


几个比较重要的调度函数

调度宏

#define _ST_SWITCH_CONTEXT(_thread)       \
    ST_BEGIN_MACRO                        \
    ST_SWITCH_OUT_CB(_thread);            \
    if (!MD_SETJMP((_thread)->context)) { \
      _st_vp_schedule();                  \
    }                                     \
    ST_DEBUG_ITERATE_THREADS();           \
    ST_SWITCH_IN_CB(_thread);             \
    ST_END_MACRO


这个宏的特色之处就在,setjmp之后,他会直接跳进_st_vp_schedule()函数里面。st_sleep  st_read st_write等函数,都是其针对不同业务的封装。


整个调度过程


外部必须不断的调度st_sleep() st_read() st_write(),因为这些都是驱动力,在调用了这些之后,库会把这些线程放到ioq  timeq 或者runq等几个队列中,然后重新保存这些函数的context,调用vp_schduel函数,最终会调用到idle_thread的执行函数执行epoll_wait,如此不断的循环。



终于搞通了。

那么最后一个结论

如果ilde_thead的while()循环退出了。那么正st库也就完蛋了


展开阅读全文

没有更多推荐了,返回首页