srs代码学习(2)- 线程模型

来源:互联网 发布:智慧树网络课程app 编辑:程序博客网 时间:2024/05/18 03:00

代码阅读到现在。发现srs有两大类线程。一个是主线程的逻辑。



一个是监听线程簇。结构图如下



一定还有第三种线程模型,负责底层的多路分发。今天还没有发现。


2016.08.25--21:00

仔细阅读了state-threads的介绍,特别是setjmp()和longjmp()函数,发现了一下代码

[cpp] view plain copy
  1. _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg,  
  2.                    int joinable, int stk_size)  
  3. {  
  4.   _st_thread_t *thread;  
  5.   _st_stack_t *stack;  
  6.   void **ptds;  
  7.   char *sp;  
  8. #ifdef __ia64__  
  9.   char *bsp;  
  10. #endif  
  11.   
  12.   /* Adjust stack size */  
  13.   if (stk_size == 0)  
  14.     stk_size = ST_DEFAULT_STACK_SIZE;  
  15.   stk_size = ((stk_size + _ST_PAGE_SIZE - 1) / _ST_PAGE_SIZE) * _ST_PAGE_SIZE;  
  16.   stack = _st_stack_new(stk_size);  
  17.   if (!stack)  
  18.     return NULL;  
  19.   
  20.   /* Allocate thread object and per-thread data off the stack */  
  21. #if defined (MD_STACK_GROWS_DOWN)  
  22.   sp = stack->stk_top;  
  23. #ifdef __ia64__  
  24.   /* 
  25.    * The stack segment is split in the middle. The upper half is used 
  26.    * as backing store for the register stack which grows upward. 
  27.    * The lower half is used for the traditional memory stack which 
  28.    * grows downward. Both stacks start in the middle and grow outward 
  29.    * from each other. 
  30.    */  
  31.   sp -= (stk_size >> 1);  
  32.   bsp = sp;  
  33.   /* Make register stack 64-byte aligned */  
  34.   if ((unsigned long)bsp & 0x3f)  
  35.     bsp = bsp + (0x40 - ((unsigned long)bsp & 0x3f));  
  36.   stack->bsp = bsp + _ST_STACK_PAD_SIZE;  
  37. #endif  
  38.   sp = sp - (ST_KEYS_MAX * sizeof(void *));  
  39.   ptds = (void **) sp;  
  40.   sp = sp - sizeof(_st_thread_t);  
  41.   thread = (_st_thread_t *) sp;  
  42.   
  43.   /* Make stack 64-byte aligned */  
  44.   if ((unsigned long)sp & 0x3f)  
  45.     sp = sp - ((unsigned long)sp & 0x3f);  
  46.   stack->sp = sp - _ST_STACK_PAD_SIZE;  
  47. #elif defined (MD_STACK_GROWS_UP)  
  48.   sp = stack->stk_bottom;  
  49.   thread = (_st_thread_t *) sp;  
  50.   sp = sp + sizeof(_st_thread_t);  
  51.   ptds = (void **) sp;  
  52.   sp = sp + (ST_KEYS_MAX * sizeof(void *));  
  53.   
  54.   /* Make stack 64-byte aligned */  
  55.   if ((unsigned long)sp & 0x3f)  
  56.     sp = sp + (0x40 - ((unsigned long)sp & 0x3f));  
  57.   stack->sp = sp + _ST_STACK_PAD_SIZE;  
  58. #else  
  59. #error Unknown OS  
  60. #endif  
  61.   
  62.   memset(thread, 0, sizeof(_st_thread_t));  
  63.   memset(ptds, 0, ST_KEYS_MAX * sizeof(void *));  
  64.   
  65.   /* Initialize thread */  
  66.   thread->private_data = ptds;  
  67.   thread->stack = stack;  
  68.   thread->start = start;  
  69.   thread->arg = arg;  
  70.   
  71. #ifndef __ia64__  
  72.   _ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main);  
  73. #else  
  74.   _ST_INIT_CONTEXT(thread, stack->sp, stack->bsp, _st_thread_main);  
  75. #endif  
  76.   
  77.   /* If thread is joinable, allocate a termination condition variable */  
  78.   if (joinable) {  
  79.     thread->term = st_cond_new();  
  80.     if (thread->term == NULL) {  
  81.       _st_stack_free(thread->stack);  
  82.       return NULL;  
  83.     }  
  84.   }  
  85.   
  86.   /* Make thread runnable */  
  87.   thread->state = _ST_ST_RUNNABLE;  
  88.   _st_active_count++;  
  89.   _ST_ADD_RUNQ(thread);  
  90. #ifdef DEBUG  
  91.   _ST_ADD_THREADQ(thread);  
  92. #endif  
  93.   
  94.   return thread;  
  95. }  
这个是创建线程的函数。仔细搜索其中的thread变量,会发现其实本身并没有创建一个新的线程,额只是在堆上分配了一个新的stack.代码如下

thread = (_st_thread_t *) sp;

这个thread只是一个结构体。

这么说来,整个程序都是在一个主线程上做调用。而不存在线程的切换。一系列同步锁等问题。这一点还有在以后代码阅读中在做体会。


虽然大概搞明白了,但这里面的理念包括代码,已经超越我的认知了。这怎么可能呢?


2016-08-26 15:00

发现了一个新的线程簇,用了做rtmp协议的收发,结构图如下




分析过好,发现这个类线程簇是在上一类线程的基础上。增加了rtmpser模块接收或者发送数据,由于有了消息的概念所以多了几个新的类,包括SrsCommonMessage类,



这个类的是rtmp消息专用类,虽然在名字中没有体现出来。