dxWorld线程模型
dxWorld继承dxThreadingBase,dxIThreadingDefaultImplProvider用来实现多线程调度。
dxIThreadingDefaultImplProvider仅用来将dxWorld中的实现传送给dxThreadingBase。
dxThreadingBase封装了一个多线程调度接口,但是内部它将具体的事务委托给具体的实现。
dxThreadingBase通过接口dxThreadingFunctionsInfo调用具体的多线程调度实现。
dxThreadingFunctionsInfo
dxThreadingFunctionsInfo其实就是一个函数表:
static const dxThreadingFunctionsInfo g_builtin_threading_functions =
{
sizeof(dxThreadingFunctionsInfo), // unsigned struct_size;
&AllocMutexGroup, // dMutexGroupAllocFunction *alloc_mutex_group;
&FreeMutexGroup, // dMutexGroupFreeFunction *free_mutex_group;
&LockMutexGroupMutex, // dMutexGroupMutexLockFunction *lock_group_mutex;
&UnlockMutexGroupMutex, // dMutexGroupMutexUnlockFunction *unlock_group_mutex;
&AllocThreadedCallWait, // dThreadedCallWaitAllocFunction *alloc_call_wait;
&ResetThreadedCallWait, // dThreadedCallWaitResetFunction *reset_call_wait;
&FreeThreadedCallWait, // dThreadedCallWaitFreeFunction *free_call_wait;
&PostThreadedCall, // dThreadedCallPostFunction *post_call;
&AlterThreadedCallDependenciesCount, // dThreadedCallDependenciesCountAlterFunction *alter_call_dependencies_count;
&WaitThreadedCall, // dThreadedCallWaitFunction *wait_call;
&RetrieveThreadingThreadCount, // dThreadingImplThreadCountRetrieveFunction *retrieve_thread_count;
&PreallocateResourcesForThreadedCalls, // dThreadingImplResourcesForCallsPreallocateFunction *preallocate_resources_for_calls;
// &TryLockMutexGroupMutex, // dMutexGroupMutexTryLockFunction *trylock_group_mutex;
};
dxThreadingFunctionsInfo将具体的调用委托给具体的多线程实现,它自己仅仅起到一个接口的作用。
如它的一个函数AllocMutexGroup,可以看到它仅仅是委托给具体的实现去做。
static dMutexGroupID AllocMutexGroup(dThreadingImplementationID impl, dmutexindex_t Mutex_count, const char *const *Mutex_names_ptr/*=NULL*/)
{
dIMutexGroup *mutex_group = ((dxIThreadingImplementation *)impl)->AllocMutexGroup(Mutex_count);
return (dMutexGroupID)mutex_group;
}
实现层
具体的多线程调度实现有一组模板类来完成,它们是dxtemplateJobListContainer,dxtemplateJobListSelfHandler,dxtemplateThreadingImplementation
通过模板类的参数来完成类型组装。dxSelfThreadedThreading就是一个具体的实现。它其实是一个伪装的多线程实现。
真正的多线程实现是dxMultiThreadedThreading。下面是代码片段,被剪接到以前便于查看。
typedef dxtemplateJobListContainer<dxFakeLull, dxFakeMutex, dxFakeAtomicsProvider> dxSelfThreadedJobListContainer;
typedef dxtemplateJobListSelfHandler<dxSelfWakeup, dxSelfThreadedJobListContainer> dxSelfThreadedJobListHandler;
typedef dxtemplateThreadingImplementation<dxSelfThreadedJobListContainer, dxSelfThreadedJobListHandler> dxSelfThreadedThreading;
/*extern */dThreadingImplementationID dThreadingAllocateSelfThreadedImplementation()
{
dxSelfThreadedThreading *threading = new dxSelfThreadedThreading();
if (threading != NULL && !threading->InitializeObject())
{
delete threading;
threading = NULL;
}
dxIThreadingImplementation *impl = threading;
return (dThreadingImplementationID)impl;
}
typedef dxtemplateJobListContainer<dxtemplateThreadedLull<dxCondvarWakeup, dxOUAtomicsProvider, false>, dxMutexMutex, dxOUAtomicsProvider> dxMultiThreadedJobListContainer;
typedef dxtemplateJobListThreadedHandler<dxCondvarWakeup, dxMultiThreadedJobListContainer> dxMultiThreadedJobListHandler;
typedef dxtemplateThreadingImplementation<dxMultiThreadedJobListContainer, dxMultiThreadedJobListHandler> dxMultiThreadedThreading;
/*extern */dThreadingImplementationID dThreadingAllocateMultiThreadedImplementation()
{
#if dBUILTIN_THREADING_IMPL_ENABLED
dxMultiThreadedThreading *threading = new dxMultiThreadedThreading();
if (threading != NULL && !threading->InitializeObject())
{
delete threading;
threading = NULL;
}
#else
dxIThreadingImplementation *threading = NULL;
#endif // #if dBUILTIN_THREADING_IMPL_ENABLED
dxIThreadingImplementation *impl = threading;
return (dThreadingImplementationID)impl;
}
在分析这些模板类前,先看看它的模板参数类是干什么的。
dxEventWakeup,dxCondvarWakeup
dxEventWakeup(win32),dxCondvarWakeup(posix)
dxEventWakeup创建一个自动Event对象(win32),当几个线程调用WaitWakeup等在那里时。
其他线程可以通过调用WakeupAThread来唤醒一个线程,或者通过WakeupAllThreads
来唤醒全部等待的线程。ResetWakeup重新将Event设置成无信号状态。
dxCondvarWakeup实现类似机制。
dxtemplateThreadedLull
有4个函数
RegisterToLull增加计数
UnregisterFromLull减少计数
WaitForLullAlarm等待醒来
SignalLullAlarmIfAnyRegistrants让一个等待的线程醒来
dxCriticalSectionMutex
LockMutex 进入临界区对象
TryLockMutex 如果临界区对象没有其他线程拥有,则进入临界区。
否则立刻返回bool。
UnlockMutex 释放临界区对象
dxtemplateJobListContainer
有一个成员dxThreadedJobInfo *m_job_list。dxThreadedJobInfo是一个单向链表。
dxThreadedJobInfo仅仅是一个数据结构,并没有封装算法。