WebRTC三大线程

909 阅读2分钟

webrtc的所有其他线程都是由三大线程所创建的, 而这三大线程是在创建peer connectionfactory的时候所创建的,线程参数如果传空, 就会在内部逻辑自行创建这三个线程, 并通过Start()函数启动线程.

三大线程有

  • 信号线程: 负责与应用层交互, 上层调用API, 并在API内部进行了应用线程到信号线程的切换,当进行底层逻辑处理的时候就会从信号线程切换到工作线程, 默认把主线程当作信号线程.

  • 工作线程: 负责内部逻辑处理, 是最为核心的线程,所有底层的核心逻辑都是由此线程完成.

  • 网络线程: 负责网络数据包的收发.

三个线程的协作关系, 例如:

网络线程收到数据包之后, 首先把数据包交给工作线程, 由工作线程做一些逻辑处理(把rtp包头去掉, 保留payload数据, 将多个rtp包组成一个视频帧), 如果应用层想要获取底层的反馈信息, 工作线程就会将相应的数据交个信号线程, 由信号线程传个应用层.

线程的创建

POSIX平台API : pthread_create()

Win平台API : CreateThread()

  • lpThreadAttributes : 线程属性, NULL表示默认线程属性

  • dwStackSize : 线程所占用的堆栈大小, 0表示默认堆栈大小

  • IpStartAddress : 线程启动后要执行的函数的函数地址.

  • lpParameter : IpStartAddress所指向的函数的参数, 只能有一个参数

  • dwCreationFlags : 创建时设置的flag, 0表示线程创建好后立即参与线程调度

  • lpThreadId : 如果不为空, 则线程创建好后就会返回线程id, 是一个输出参数.

  • tidp : 在变量中存放关于此线程的基本信息.

  • attr : 线程属性, 一般使用相关API对其初始化, 即使用默认的属性.

  • start_rtn(void*) : 线程启动时的执行函数.

  • arg : 线程启动时的执行函数的参数.

接口调用:

线程的运行

执行函数的基本运行逻辑 内部为一个while死循环 -- 从队列中取出消息 然后交给Dispatch处理消息, 在dispatch中又把控制权交给了发送线程.发送线程把要执行的逻辑交给执行线程.

while(true) {
    ...
    Get(&msg, ...);
    ...
    Dispatch(&msg);
    ...
}
Dispatch(Message* pmsg) {
    ...
    pmsg->handle->OnMessage(pmsg);
    ...
}

下图是native版本的三大线程创建的代码:

下图是Thread::Start()函数的代码逻辑, 其中创建了线程manager

下图是preRun()函数的实现, 其中当线程启动后才将当前线程与之前创建好的Thread对象进行绑定, thread->run()方法里就是上面提到的While循环运行逻辑了.