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变量
};

你可能感兴趣的:(X265)