x265多线程-BondedTaskGroup

任务组BondedTaskGroup的作用是可以征用若干sleep线程一起执行某一任务

/* Any worker thread may enlist the help of idle worker threads from the same
 * job provider. They must derive from this class and implement the
 * processTasks() method.  To use, an instance must be instantiated by a worker
 * thread (referred to as the master thread) and then tryBondPeers() must be
 * called. If it returns non-zero then some number of slave worker threads are
 * already in the process of calling your processTasks() function. The master
 * thread should participate and call processTasks() itself. When
 * waitForExit() returns, all bonded peer threads are guaranteed to have
 * exitied processTasks(). Since the thread count is small, it uses explicit
 * locking instead of atomic counters and bitmasks
 * 任务组,可以征用若干线程一起执行某一工作 */
class BondedTaskGroup
{
public:

    Lock              m_lock;
    ThreadSafeInteger m_exitedPeerCount;	// 当前BondedTaskGroup中退出的线程数量
    int               m_bondedPeerCount;	// 当前BondedTaskGroup所拥有的线程数量
    int               m_jobTotal;
    int               m_jobAcquired;

    BondedTaskGroup()  { m_bondedPeerCount = m_jobTotal = m_jobAcquired = 0; }

    /* Do not allow the instance to be destroyed before all bonded peers have
     * exited processTasks() */
    ~BondedTaskGroup() { waitForExit(); }

    /* Try to enlist the help of idle worker threads on most recently associated
     * with the given job provider and "bond" them to work on your tasks. Up to
     * maxPeers worker threads will call your processTasks() method. 
	 * 在指定jobProvider里征用线程到自己的BondedTaskGroup里 */
    int tryBondPeers(JobProvider& jp, int maxPeers)
    {
		// 在指定jp中征用线程到该BondedTaskGroup里,返回被征用的线程数量
        int count = jp.m_pool->tryBondPeers(maxPeers, jp.m_ownerBitmap, *this);
		// 累计当前BondedTaskGroup的线程数量
        m_bondedPeerCount += count;
        return count;
    }

    /* Try to enlist the help of any idle worker threads and "bond" them to work
     * on your tasks. Up to maxPeers worker threads will call your
     * processTasks() method. 
	 * 在指定ThreadPool里征用线程到自己的BondedTaskGroup里 */
    int tryBondPeers(ThreadPool& pool, int maxPeers)
    {
		// 可以征用任何sleep状态下的线程到该BondedTaskGroup里,返回被征用的线程数量
        int count = pool.tryBondPeers(maxPeers, ALL_POOL_THREADS, *this);
		// 累计当前BondedTaskGroup的线程数量
        m_bondedPeerCount += count;
        return count;
    }

    /* Returns when all bonded peers have exited processTasks(). It does *NOT*
     * ensure all tasks are completed (but this is generally implied). 
	 * 等待所有被征用的线程执行task完毕并退出 */
    void waitForExit()
    {
		// 得到退出的peer数量
        int exited = m_exitedPeerCount.get();
		// 持续阻塞,直到退出的线程数量 == 被征用的线程数量
        while (m_bondedPeerCount != exited)
            exited = m_exitedPeerCount.waitForChange(exited);
    }

    /* Derived classes must define this method. The worker thread ID may be
     * used to index into thread local data, or ignored.  The ID will be between
     * 0 and jp.m_numWorkers - 1 
	 * 被征用的线程执行的工作 */
    virtual void processTasks(int workerThreadId) = 0;
};

所有需要使用BondedTaskGroup功能的对象都必须继承并重写processTasks()函数。在WorkerThread的主函数threadMain()里面,线程首先会进行BondedTaskGroup检查,若线程被征用到某一master BondedTaskGroup中,则执行相应的工作

		// 先检查当前线程是否被征用,若被征用到m_bondMaster则执行task
		if (m_bondMaster)
		{
			// 执行m_bondMaster的task
			m_bondMaster->processTasks(m_id);
			// 执行完毕线程退出,m_exitedPeerCount累加
			m_bondMaster->m_exitedPeerCount.incr();
			// 置空
			m_bondMaster = NULL;
		}

你可能感兴趣的:(X265)