代码阅读到现在。发现srs有两大类线程。一个是主线程的逻辑。
一个是监听线程簇。结构图如下
一定还有第三种线程模型,负责底层的多路分发。今天还没有发现。
2016.08.25--21:00
仔细阅读了state-threads的介绍,特别是setjmp()和longjmp()函数,发现了一下代码
- _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;
- #ifdef __ia64__
- char *bsp;
- #endif
- /* 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 */
- #if defined (MD_STACK_GROWS_DOWN)
- sp = stack->stk_top;
- #ifdef __ia64__
- /*
- * The stack segment is split in the middle. The upper half is used
- * as backing store for the register stack which grows upward.
- * The lower half is used for the traditional memory stack which
- * grows downward. Both stacks start in the middle and grow outward
- * from each other.
- */
- sp -= (stk_size >> 1);
- bsp = sp;
- /* Make register stack 64-byte aligned */
- if ((unsigned long)bsp & 0x3f)
- bsp = bsp + (0x40 - ((unsigned long)bsp & 0x3f));
- stack->bsp = bsp + _ST_STACK_PAD_SIZE;
- #endif
- 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;
- #elif defined (MD_STACK_GROWS_UP)
- sp = stack->stk_bottom;
- thread = (_st_thread_t *) sp;
- sp = sp + sizeof(_st_thread_t);
- ptds = (void **) sp;
- sp = sp + (ST_KEYS_MAX * sizeof(void *));
- /* Make stack 64-byte aligned */
- if ((unsigned long)sp & 0x3f)
- sp = sp + (0x40 - ((unsigned long)sp & 0x3f));
- stack->sp = sp + _ST_STACK_PAD_SIZE;
- #else
- #error Unknown OS
- #endif
- 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;
- #ifndef __ia64__
- _ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main);
- #else
- _ST_INIT_CONTEXT(thread, stack->sp, stack->bsp, _st_thread_main);
- #endif
- /* 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);
- #ifdef DEBUG
- _ST_ADD_THREADQ(thread);
- #endif
- return thread;
- }
thread = (_st_thread_t *) sp;
这个thread只是一个结构体。
这么说来,整个程序都是在一个主线程上做调用。而不存在线程的切换。一系列同步锁等问题。这一点还有在以后代码阅读中在做体会。
虽然大概搞明白了,但这里面的理念包括代码,已经超越我的认知了。这怎么可能呢?
2016-08-26 15:00
发现了一个新的线程簇,用了做rtmp协议的收发,结构图如下
分析过好,发现这个类线程簇是在上一类线程的基础上。增加了rtmpser模块接收或者发送数据,由于有了消息的概念所以多了几个新的类,包括SrsCommonMessage类,
这个类的是rtmp消息专用类,虽然在名字中没有体现出来。