webRTC base库 Event分析
Linux下Event的实现
利用了poix线程锁pthread_mutex_t和条件变量pthread_cond_t实现事件的等待和触发
主要的3个接口:
1. void Set();
2. void Reset();
3. bool Wait(int millseconds);
类内定义了static const int kForever = -1;作为阻塞条件的判断
Wait可以选择超时解锁用法 Wait(5000); // wait most 5s
也可以选择等待解锁用法 Wait(-1); // wait unitl Set is called
wait接口的伪代码实现:{
pthread_mutex_lock(&mutex_);
if (等待解锁) {
while (!status_ && ret == 0)
ret = pthread_cond_wait(&cond_, &mutex_);
} else {
while (!status_ && ret == 0)
ret = pthread_cond_time_wait(&cond, &mutex, &outtime);
}
pthread_mutex_unlock(&mutex_);
}
Set接口会发出广播信号 解锁所有Wait
Set接口伪代码实现 {
pthread_mutex_lock(&mutex_);
status_ = true;
pthread_cond_broadcast(&cond_);
pthread_mutex_unlock(&mutex_);
}
Reset接口重置Event事件的使用 也就是使得调用后的Wait重新有效 一般会在Wait的下一步使用吧.
Reset接口伪代码实现 {
pthread_mutex_lock(&mutex_);
status_ = false;
pthread_mutex_unlock(&mutex_);
}
注意status_变量的使用,是为了防止出现线程信号已经发出但还Wait还没有进入等待的情况
从逻辑上大概就是:
thread A thread B
1. signal();
2. wait();
大致上就是A线程的信号比B线程的等待先执行 导致B线程死锁
示例代码
#include <iostream>
#include "webrtc/base/event.h"
extern "C" {
#include <sys/time.h>
#include <signal.h>
}
using namespace rtc;
Event e1(0, 0);
void sigcall(int num) {
std::cout << "signal rcv" << std::endl;
e1.Set();
}
int main() {
struct timeval ts, te;
signal(SIGINT, sigcall);
gettimeofday(&ts, NULL);
e1.Wait(-1);
gettimeofday(&te, NULL);
std::cout << "cost time" << te.tv_sec - ts.tv_sec<< std::endl;
return 0;
}
运行编译出的bin程序 按下Ctrl + C 可以使得程序提出并打印阻塞等待的时间
示例demo git仓库
git@github.com:sliver-chen/webRTCTutorial.git