x265多線程-線程安全型整型變量

/* This class is intended for use in signaling state changes safely between CPU
 * cores. One thread should be a writer and multiple threads may be readers. The
 * mutex's main purpose is to serve as a memory fence to ensure writes made by
 * the writer thread are visible prior to readers seeing the m_val change. Its
 * secondary purpose is for use with the condition variable for blocking waits 
 * 
 * ThreadSafeInteger主要是針對整型變量的線程安全操作的一套封裝 */
class ThreadSafeInteger
{
public:

	// 初始化互斥鎖、條件變量,並將integer初始化爲0
	ThreadSafeInteger()
	{
		m_val = 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");
		}
	}

	// 析構函數銷燬互斥鎖和條件變量
	~ThreadSafeInteger()
	{
		pthread_cond_destroy(&m_cond);
		pthread_mutex_destroy(&m_mutex);
	}

	// 阻塞等待直到m_val與prev不同,並返回m_val的值
	int waitForChange(int prev)
	{
		pthread_mutex_lock(&m_mutex);
		// 若m_val與prev相等,則阻塞等待,
		if (m_val == prev)
			pthread_cond_wait(&m_cond, &m_mutex);
		pthread_mutex_unlock(&m_mutex);
		return m_val;
	}

	// 得到m_val的值
	int get()
	{
		pthread_mutex_lock(&m_mutex);
		int ret = m_val;
		pthread_mutex_unlock(&m_mutex);
		return ret;
	}

	// 返回m_val的原始值,同時將其自增n
	int getIncr(int n = 1)
	{
		pthread_mutex_lock(&m_mutex);
		int ret = m_val;
		m_val += n;
		pthread_mutex_unlock(&m_mutex);
		return ret;
	}

	// 將m_val賦值爲newval
	// 這裏有問題,當線程因爲waitForChange()函數阻塞,需要m_val == prev時才能被喚醒
	// 那麼,當這裏set的newval值依然與m_val值相等時,同樣喚醒了之前被阻塞的線程
	// 修改方案:
	// 1.	waitForChange()中
	// 				if (m_val == prev)
	// 					pthread_cond_wait(&m_cond, &m_mutex);
	//		改爲
	//				while(m_val == prev)
	//					pthread_cond_wait(&m_cond, &m_mutex);
	// 2.	set()中
	//				m_val = newval;
	//				pthread_cond_broadcast(&m_cond);
	//		改爲
	//				if (m_val != newval){
	//					m_val = newval;
	//					pthread_cond_broadcast(&m_cond);					
	//				}
	void set(int newval)
    {
        pthread_mutex_lock(&m_mutex);
        m_val = newval;
        pthread_cond_broadcast(&m_cond);
        pthread_mutex_unlock(&m_mutex);
    }

	// 喚醒所有被waitForChange()函數阻塞的線程
    void poke(void)
    {
        /* awaken all waiting threads, but make no change */
        pthread_mutex_lock(&m_mutex);
        pthread_cond_broadcast(&m_cond);
        pthread_mutex_unlock(&m_mutex);
    }

	// m_val自增
    void incr()
    {
        pthread_mutex_lock(&m_mutex);
        m_val++;
        pthread_cond_broadcast(&m_cond);
        pthread_mutex_unlock(&m_mutex);
    }

protected:

    pthread_mutex_t m_mutex;	// 互斥鎖
    pthread_cond_t  m_cond;		// 條件變量
    int             m_val;		// integer變量
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章