SRS源码中的Thread是一层套一层,最终的Thread类是在 srs_app_thread.cpp 的 SrsThread 类
这里我们暂且先放下协程的概念,把它当线程来看,其逻辑如下:
1. 在start() 方法中创建线程:
int SrsThread::start()
{
int ret = ERROR_SUCCESS;
if(tid) {
srs_info("thread %s already running.", _name);
return ret;
}
if((tid = st_thread_create(thread_fun, this, (_joinable? 1:0), 0)) == NULL){
ret = ERROR_ST_CREATE_CYCLE_THREAD;
srs_error("st_thread_create failed. ret=%d", ret);
return ret;
}
disposed = false;
// we set to loop to true for thread to run.
loop = true;
// wait for cid to ready, for parent thread to get the cid.
while (_cid < 0) {
st_usleep(10 * 1000);
}
// now, cycle thread can run.
can_run = true;
return ret;
}
2. 执行的函数是 thread_fun,参数是其本身即: this,再实际调用 this->thread_cycle():
void* SrsThread::thread_fun(void* arg)
{
SrsThread* obj = (SrsThread*)arg;
srs_assert(obj);
obj->thread_cycle();
// for valgrind to detect.
SrsThreadContext* ctx = dynamic_cast<SrsThreadContext*>(_srs_context);
if (ctx) {
ctx->clear_cid();
}
st_thread_exit(NULL);
return NULL;
}
3. thread_cycle() 实现如下:
void SrsThread::thread_cycle()
{
int ret = ERROR_SUCCESS;
_srs_context->generate_id();
srs_info("thread %s cycle start", _name);
_cid = _srs_context->get_id();
srs_assert(handler);
handler->on_thread_start();
// thread is running now.
really_terminated = false;
// wait for cid to ready, for parent thread to get the cid.
while (!can_run && loop) {
st_usleep(10 * 1000);
}
while (loop) {
if ((ret = handler->on_before_cycle()) != ERROR_SUCCESS) {
srs_warn("thread %s on before cycle failed, ignored and retry, ret=%d", _name, ret);
goto failed;
}
srs_info("thread %s on before cycle success", _name);
if ((ret = handler->cycle()) != ERROR_SUCCESS) {
if (!srs_is_client_gracefully_close(ret) && !srs_is_system_control_error(ret)) {
srs_warn("thread %s cycle failed, ignored and retry, ret=%d", _name, ret);
}
goto failed;
}
srs_info("thread %s cycle success", _name);
if ((ret = handler->on_end_cycle()) != ERROR_SUCCESS) {
srs_warn("thread %s on end cycle failed, ignored and retry, ret=%d", _name, ret);
goto failed;
}
srs_info("thread %s on end cycle success", _name);
failed:
if (!loop) {
break;
}
// to improve performance, donot sleep when interval is zero.
// @see: https://github.com/ossrs/srs/issues/237
if (cycle_interval_us != 0) {
st_usleep(cycle_interval_us);
}
}
// readly terminated now.
really_terminated = true;
handler->on_thread_stop();
srs_info("thread %s cycle finished", _name);
}
其核心就是循环调用 变量 ISrsThreadHandler* handler (构造函数的参数赋值进来的)如下三个函数:
virtual int on_before_cycle();
virtual int cycle() = 0;
virtual int on_end_cycle();
4. 停止线程循环可以调用 stop_loop() :
void SrsThread::stop_loop()
{
loop = false;
}
但是仔细看使用线程的代码会发现,ISrsThreadHandler* handler 这个变量还是被封装了。
如 SrsOneCycleThread 自己继承自 ISrsThreadHandler
class SrsOneCycleThread : public internal::ISrsThreadHandler
{
private:
internal::SrsThread* pthread;
ISrsOneCycleThreadHandler* handler;
//...
}
在new SrsThread 时,将自己的this指针传入,当作SrsThread 的 handler变量,
然后自己的线程函数中重新调用自己的变量: ISrsOneCycleThreadHandler* handler
int SrsOneCycleThread::cycle()
{
int ret = handler->cycle();
pthread->stop_loop();
return ret;
}
void SrsOneCycleThread::on_thread_start()
{
handler->on_thread_start();
}
int SrsOneCycleThread::on_before_cycle()
{
return handler->on_before_cycle();
}
int SrsOneCycleThread::on_end_cycle()
{
return handler->on_end_cycle();
}
void SrsOneCycleThread::on_thread_stop()
{
handler->on_thread_stop();
}
注意,虽然 ISrsOneCycleThreadHandler 和 ISrsThreadHandler 这两个接口函数都一样,但是并没有继承关系。
来源:oschina
链接:https://my.oschina.net/u/4417460/blog/3531896