最近在写服务端逻辑业务时,有很多处理与时间相关,需要在不影响主线程的情况下,间隔一段时间后做某种处理。如:录制一段3s的远程视屏,主线程运行触发startRecord后,等3s,再发送stopRecord,若在主线程sleep(3);则这3s内,主线程将不能处理自己的逻辑业务;
首先,通过gettimeofday函数获取当前时间;函数如下所示:
#include <sys/time.h>
//系统64位
uint64_t tm64()
{
struct timeval timev;
uint64_t now;
gettimeofday(&timev, NULL);
now = (uint64_t)time.tv_sec * (uint64_t)1000000 + timev.tv_usec;
return now;
}
2.在事件触发时,将当前时间ct与定时的时间相加得到想要触发的时间time1,在while中不断的获取当前时间ct,当ct大于等于time1时执行事件;下面是一个时间调度的类;
class CTimeManager
{
public:
CTimeManager();
~CTimeManager();
void *timeDataProcess(void *arg);
bool startTime();
bool timeThread();
void setMainManager(CMainManager * mainManager)
{
m_cMainManager = mainManager;
}
void setStopVedio(bool opt);
private:
pthread_t m_nTimeThread;
bool isStart;
bool m_boStopVedio;
unsigned long m_nTimeStopVedio;
CMainManager *m_cMainManager;
};
CTimeManager::CTimeManager(){
m_nTimeThread = 0;
isStart = false;
m_nTimeStopVedio = tm64() + 1000 * 1000 *3;
m_boStopVedio = false;
}
CTimeManager::~CTimeManager(){
if(isStart){
isStart = false;
pthread_join(m_nTimeThread, NULL);
}
}
bool CTimeManager::startTime()
{
if(!timeThread())
{
return false;
}
isStart = true;
return true;
}
bool CTimeManager::timeThread()
{
if(pthread_create(&m_nTimeThread, NULL, timeDataProcess, (void *)this) != 0)
{
return false;
}
return true;
}
void * CTimeManager::timeDataProcess(void *arg)
{
CTimeManager * time = (CTimeManager *)arg;
while(time->isStart){
unsigned long curTick = tm64();
if(time->m_boStopVedio){
if(curTick > m_timeStopVedio)
{
//具体执行函数
time->m_cMainManager->stopVedio();
m_timeStopVedio = tm64() + 1000 * 1000 * 5;
}
}
}
}
void CTimeManager::setStopVedio(bool opt)
{
m_boStopVedio = opt;
if(opt)
m_nTimeStopVedio = tm64() + 1000 * 1000 * 3;//3后执行函数
}
3.在处理接收业务的主线程中,调用时间调度线程;
class CMainManager
{
public:
CMainManager(){}
~CMainManager(){}
void init();
void startVedio();
void stopVedio();
private:
CTimeManager m_cTimeManager;
};
void CMainManager::init()
{
m_cTimeManager.setMainManager(this);
if(!m_cTimeManager.startTime())
{
printf("时间线程启动失败。。。\n");
}
}
void CMainManager::startVedio()
{
printf("开始录制视频\n");
//启动结束录制视频的定时器
m_cTimeManager.setStopVedio(true);
}
void CMainManager::stopVedio()
{
printf("停止录制视频\n");
}
CMainManager的启用函数init()放在main函数中进行就可以了,一般可以将其作为一个单例类来使用;