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; // 信號量
};