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循环运行逻辑了.