x265中的event类模拟生产者消费者模型
生产者生产临界资源,并通过条件变量通知消费者
消费者消耗临界资源,若无临界资源则被阻塞等待生产者生产临界资源
/*
模拟生产者消费者模型
*/
class Event
{
public:
// 构造函数,初始化信号量m_counter = 0,初始化互斥量m_mutex和条件变量m_cond
Event()
{
m_counter = 0;
if (pthread_mutex_init(&m_mutex, NULL) ||
pthread_cond_init(&m_cond, NULL))
{
x265_log(NULL, X265_LOG_ERROR, "fatal: unable to initialize conditional variable\n");
}
}
// 析构销毁互斥量m_mutex和条件变量m_cond
~Event()
{
pthread_cond_destroy(&m_cond);
pthread_mutex_destroy(&m_mutex);
}
// 消费者:消耗一个资源,若资源数 = 0,则被阻塞,等待生产者生产资源
void wait()
{
pthread_mutex_lock(&m_mutex);
/* blocking wait on conditional variable, mutex is atomically released
* while blocked. When condition is signaled, mutex is re-acquired */
while (!m_counter)
pthread_cond_wait(&m_cond, &m_mutex);
m_counter--;
pthread_mutex_unlock(&m_mutex);
}
// 生产者:生产一个资源,并通过条件变量m_cond通知因资源不够而被阻塞的消费者
void trigger()
{
pthread_mutex_lock(&m_mutex);
if (m_counter < UINT_MAX)
m_counter++;
/* Signal a single blocking thread */
pthread_cond_signal(&m_cond);
pthread_mutex_unlock(&m_mutex);
}
// 消费者:最多等待waitms毫秒,若在waitms毫秒内等到了资源则消耗它,
// 若没有等到则返回超时
bool timedWait(uint32_t waitms)
{
bool bTimedOut = false;
pthread_mutex_lock(&m_mutex);
if (!m_counter)
{
// 基于waitms构造时间ts
struct timeval tv;
struct timespec ts;
gettimeofday(&tv, NULL);
/* convert current time from (sec, usec) to (sec, nsec) */
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
ts.tv_nsec += 1000 * 1000 * (waitms % 1000); /* add ms to tv_nsec */
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000); /* overflow tv_nsec */
ts.tv_nsec %= (1000 * 1000 * 1000); /* clamp tv_nsec */
ts.tv_sec += waitms / 1000; /* add seconds */
/* blocking wait on conditional variable, mutex is atomically released
* while blocked. When condition is signaled, mutex is re-acquired.
* ts is absolute time to stop waiting */
// 最多等待ts时间,直到生产者signal或超时,返回是否超时
bTimedOut = pthread_cond_timedwait(&m_cond, &m_mutex, &ts) == ETIMEDOUT;
}
// 若有资源则进行消耗
if (m_counter > 0)
{
m_counter--;
bTimedOut = false;
}
pthread_mutex_unlock(&m_mutex);
return bTimedOut;
}
protected:
pthread_mutex_t m_mutex; // 互斥锁
pthread_cond_t m_cond; // 条件变量
uint32_t m_counter; // 信号量
};