怎么理解state thread库?

来源:互联网 发布:java做自动化测试 编辑:程序博客网 时间:2024/06/06 10:01

主要一下几个问题

1)到底st_thread库运行的线程是谁创建的?

2)st_create_thread,创建的线程是个什么东西?

3)线程怎么切换?

4)和reactor是个什么关系?


首先还原一些关键的代码。

#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

这一堆宏,基本相当于下面的代码


int  md_setjmp(jmp_buf buf)
{
return _setjmp(env);
}


void _st_switch_context(_st_thread_t *_thread)
{
if (0 == md_setjmp((_thread)->context)))
{
_st_vp_schedule();
}
}

_st_vp_schedule()的实现为:

void _st_vp_schedule(void){  _st_thread_t *thread;  if (_ST_RUNQ.next != &_ST_RUNQ) {    /* Pull thread off of the run queue */    thread = _ST_THREAD_PTR(_ST_RUNQ.next);    _ST_DEL_RUNQ(thread);  } else {    /* If there are no threads to run, switch to the idle thread */    thread = _st_this_vp.idle_thread;  }  ST_ASSERT(thread->state == _ST_ST_RUNNABLE);  /* Resume the thread */  thread->state = _ST_ST_RUNNING;  _ST_RESTORE_CONTEXT(thread);}



与之对应的另外一个宏为:

#define _ST_RESTORE_CONTEXT(_thread)   \    ST_BEGIN_MACRO                     \    _ST_SET_CURRENT_THREAD(_thread);   \    MD_LONGJMP((_thread)->context, 1); \    ST_END_MACRO

这个宏比较简单,就是调用longjump函数。


可以看出,跳转的关键是context变量。在我们创建线程的时候

_st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg,int joinable, int stk_size){_st_thread_t *thread;_st_stack_t *stack;void **ptds;char *sp;/* Adjust stack size */if (stk_size == 0)stk_size = ST_DEFAULT_STACK_SIZE;stk_size = ((stk_size + _ST_PAGE_SIZE - 1) / _ST_PAGE_SIZE) * _ST_PAGE_SIZE;stack = _st_stack_new(stk_size);if (!stack)return NULL;/* Allocate thread object and per-thread data off the stack */sp = stack->stk_top;sp = sp - (ST_KEYS_MAX * sizeof(void *));ptds = (void **)sp;sp = sp - sizeof(_st_thread_t);thread = (_st_thread_t *)sp;/* Make stack 64-byte aligned */if ((unsigned long)sp & 0x3f)sp = sp - ((unsigned long)sp & 0x3f);stack->sp = sp - _ST_STACK_PAD_SIZE;memset(thread, 0, sizeof(_st_thread_t));memset(ptds, 0, ST_KEYS_MAX * sizeof(void *));/* Initialize thread */thread->private_data = ptds;thread->stack = stack;thread->start = start;thread->arg = arg;_ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main);/* If thread is joinable, allocate a termination condition variable */if (joinable) {thread->term = st_cond_new();if (thread->term == NULL) {_st_stack_free(thread->stack);return NULL;}}/* Make thread runnable */thread->state = _ST_ST_RUNNABLE;_st_active_count++;_ST_ADD_RUNQ(thread);return thread;}

上面是初始化的函数,我去掉了一些无用的红比如ia64位的,和堆栈向上增长的情况。一般情况下,堆栈应该是向上增长的。让我们仔细分析这段代码


经过仔细的阅读,基本读不懂这段代码。基本确定的流程就是,这个thread,在创建成功后,进入到了RUNQ队列。


那么这个队列怎么怎么执行的?在哪个线程空间里执行呢?






0 0
原创粉丝点击