1. 再次研究线程
* 线程种类
typedef int TType;
enum
{
TT_MAIN,
TT_NETWORK,
TT_DNS, // Q:for what ?
TT_CURRENT, // Q:for what?
TT_TIMER,
TT_UNKNOWN = -1,
// This private thread type is used by applications.
TT_USER_DEFINE_BASE = 1000
};
2. CRTThreadManager::InitMainThread()
主线程(自己的调用?)
CRtReactorBase::Open() line 172
CRtReactorWin32Message::Open() line 172 + 8 bytes
CRtThreadReactor::Create(int 0, CRtThreadManager::TFlag TF_JOINABLE) line 40 + 19 bytes
CRtThreadManager::CreateReactorThread(int 0, IRtReactor * 0x020a7970, CRtThread * & 0x00000000) line 368 + 41 bytes
CRtThreadManager::InitMainThread(int 0, char * * 0x00000000) line 191 + 24 bytes
CRtThreadManager::Instance() line 132 + 15 bytes
RtCoInitialize() line 179 + 5 bytes
ILDebugStart(unsigned short 33201, void * 0x00000001) line 1482
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f28, int 1) line 83 + 8 bytes
WinMainCRTStartup() line 330 + 54 bytes
KER
注:此在CRrReactorWin32Message::Open()中,将WSAAyncSelect的消息处理函数设置好。
^ 非也,此处仅仅是注册event-queue-handler的事件通知消息,与WSAAsyncselect完全无关。 2011/12/07
* 主线程(生成子线程的调用)
NTDLL! 7c92e514()
KERNEL32! 7c802542()
CRtEventThread::Wait(CRtTimeValue * 0x00000000) line 354 + 18 bytes
^ 实际上提供lock机制,very BAD NAMING ! 2011/12/07
CRtThread::Create(int 1, CRtThreadManager::TFlag TF_JOINABLE) line 99
CRtThreadReactor::Create(int 1, CRtThreadManager::TFlag TF_JOINABLE) line 36 + 16 bytes
CRtThreadManager::CreateReactorThread(int 1, IRtReactor * 0x020a7ca0, CRtThread * & 0x00000000) line 368 + 41 bytes
CRtThreadManager::SpawnNetworkThread_i() line 298 + 21 bytes
CRtThreadManager::InitMainThread(int 0, char * * 0x00000000) line 213 + 8 bytes
CRtThreadManager::Instance() line 132 + 15 bytes
// 实际上在这个instance方法中完成了所有动作:主线程初化,子线程生成,感觉是很烂的设计,instance应该只是一个SingleTon,不应该做这么多事。
RtCoInitialize() line 179 + 5 bytes
ILDebugStart(unsigned short 33201, void * 0x00000001) line 1482
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f28, int 1) line 83 + 8 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c817077()
注1:在SpawnNetworkThread_i()中负责子线程的产生。
注2:CRtThread::Create中生成子线程,在主线程wait的时候,子线程工作。
* 子线程
RtResult CRtThread::Create(...
{
...
#ifdef RT_WIN32
m_Handle = (HANDLE)::_beginthreadex(
NULL,
0,
ThreadProc,
this,
0,
(unsigned int *)(&m_Tid));
if (m_Handle == 0) {
RT_ERROR_TRACE("CRtThread::Create, _beginthreadex() failed! err=" << errno);
return RT_ERROR_UNEXPECTED;
}
#else // !RT_WIN32
...
}
注:CRtThread:;Create()中,根据是否主线程,是否Linux/Windows,有不同的线程处理方式;主线程本身是不用生成的。
* CRtThread::ThreadProc()
#ifdef RT_WIN32
unsigned WINAPI CRtThread::ThreadProc(void *aPara)
#else
void* CRtThread::ThreadProc(void *aPara)
#endif // RT_WIN32
{
CRtThread *pThread = static_cast<CRtThread *>(aPara); // Q: What's this ? 传的一个什么参数? 实际传的是CRtThread指针 this。 2011/12/07
RT_INFO_TRACE("CRtThread::ThreadProc, begin this="<<pThread);
RT_ASSERTE_RETURN(pThread, NULL);
pThread->OnThreadInit();
if (pThread->m_Type != CRtThreadManager::TT_MAIN) {
RT_ASSERTE(pThread->m_pEvent4Start);
if (pThread->m_pEvent4Start)
pThread->m_pEvent4Start->Signal();
}
pThread->OnThreadRun();
if (RT_BIT_DISABLED(pThread->m_Flag, CRtThreadManager::TF_JOINABLE) &&
++pThread->m_NeedDelete >= 2)
{
delete pThread;
}
RT_INFO_TRACE("CRtThread::ThreadProc, quit ... this="<<pThread);
return NULL;
}
3. RtBase.cpp::RtCoInitizlize()
RtResult RtCoInitialize()
{
RT_THREAD_ID threadID = CRtThreadManager::Instance()->GetThreadSelfId(); // 初始化主线程、网络子线程等等
CRtMutexGuardT<CRtMutexThread> mutexGuard(g_mutexComInit);
for (RtThreadComInitNumList::iterator it=g_threadComInitNums.begin(); it!=g_threadComInitNums.end(); ++it)
{
if (it->m_threadID == threadID)
{
RT_ASSERTE(it->m_comInitNum > 0);
++ (it->m_comInitNum);
return RT_OK;
}
}
HRESULT rv = ::CoInitialize(NULL); // 初始化Com环境等等(WTL需要的东东)
if (rv == S_OK)
{
g_threadComInitNums.push_back(RtThreadComInitNum(threadID, 1));
return RT_OK;
}
RT_WARNING_TRACE("::RtCoInitialize, CoInitialize failed! rv="<<rv<<" threadID="<<threadID);
return RT_ERROR_FAILURE;
}
Q:第三个一程什么时候产生的?
4. 第三个线程
CRtThread::Create(int 1001, CRtThreadManager::TFlag TF_DETACHED) line 39
CRtThreadManager::CreateUserTaskThread(CRtThread * & 0x00000000, CRtThreadManager::TFlag TF_DETACHED, int 0) line 335 + 31 bytes
CFileManager::Initialize(const CRtString & {0x00000000 ""}, unsigned short 0, int 0) line 170 + 26 bytes
CSDService::CSDService() line 27 + 40 bytes
CRtSingletonT<CSDService>::CRtSingletonT<CSDService>() line 39 + 76 bytes
CRtSingletonT<CSDService>::Instance() line 30 + 40 bytes
CSDService::Instance() line 21
ISDService::Instance() line 11
CConference::ChangeRoleService(unsigned long 3489660928) line 1718 + 5 bytes
CConference::JoinConference(const CConfDetailInfo & {...}, const CInfoRosterInfo & {...}, unsigned short 1, const CRtString * 0x020a94ec {0x020a9969 "tcp://192.168.1.101:443"}, int 0, unsigned long 2147483648) line 223
CConfManage::CreateConference() line 2617 + 103 bytes
CMainFrame::OnCreate(unsigned int 1, unsigned int 1, unsigned int 1, unsigned int 1) line 1879
CMainFrame::ProcessWindowMessage(HWND__ * 0x004a0b0a, unsigned int 1, unsigned int 0, long 1269856, long & -858993460, unsigned long 0) line 138 + 37 bytes
ATL::CWindowImplBaseT<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::WindowProc(HWND__ * 0x020a88c0, unsigned int 1, unsigned int 0, long 1269856) line 2110 + 37 bytes
USER32! 77d18734()
USER32! 77d2bdf1()
USER32! 77d28ea0()
USER32! 77d2ce7c()
NTDLL! 7c92e473()
USER32! 77d2e442()
USER32! 77d2e4dc()
WTL::CFrameWindowImplBase<ATL::CWindow,ATL::CWinTraits<114229248,262400> >::Create(HWND__ * 0x00000000, ATL::_U_RECT {...}, const char * 0x001366e0, unsigned long 114229248, unsigned long 262400, ATL::_U_MENUorID {...}, unsigned short 50074, void * 0x00000000) line 456 + 91 bytes
WTL::CFrameWindowImpl<CMainFrame,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::Create(HWND__ * 0x00000000, ATL::_U_RECT {...}, const char * 0x001366e0, unsigned long 114229248, unsigned long 262400, HMENU__ * 0x35970727, void * 0x00000000) line 1196
WTL::CFrameWindowImpl<CMainFrame,ATL::CWindow,ATL::CWinTraits<114229248,262400> >::CreateEx(HWND__ * 0x00000000, ATL::_U_RECT {...}, unsigned long 0, unsigned long 0, void * 0x00000000) line 1221 + 42 bytes
Run(char * 0x00151f28, int 1) line 195 + 35 bytes
LaunchConf(HINSTANCE__ * 0x00400000, char * 0x00151f28, int 1) line 318 + 13 bytes
WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x00151f28, int 1) line 85 + 20 bytes
WinMainCRTStartup() line 330 + 54 bytes
KERNEL32! 7c817077()
注:似乎是一个和SD有关的功能,以后再看细节。
5. 再次理解ConfMain.cpp::WinMain()
WinMain() {
...
if (hModule)
{
ConfClientRunProc pRunProc = (ConfClientRunProc)GetProcAddress(hModule, WT_CLIENT_RUN);
if(pRunProc)
{
DebugRunOption pRunProc1 = (DebugRunOption)GetProcAddress(hModule1, WT_DEBUG_RUN); // 获取Debug相关函数指针
DebugRunStart pRunProc2 = (DebugRunStart)GetProcAddress(hModule1, WT_DEBUG_START);
DebugRunDestory pRunProc3 = (DebugRunDestory)GetProcAddress(hModule1, WT_DEBUG_DESTORY);
// 此段为内部调试代码
char strURL[] = "http://192.168.1.92:8080";
// char strURL[] = "http://172.16.1.65:8088";
pRunProc1(WebServiceURL,(void*)strURL);
// 此段为内部调试代码
// #if 0
#ifdef __RT_DIAGNOSE__
// Start debug module
pRunProc2(); // start debug mode,同时,打开了一个网络子线程,如果非diagnose模式又如何?
RT_TRY
pRunProc(hInstance, lpCmdLine, nCmdShow); // 启动会议客户端,执行初始化,创建conference及sessoin(其间与server交互数次),消息循环,
RT_EXCEPT
// Stop debug module
pRunProc3();
#else
pRunProc(hInstance, lpCmdLine, nCmdShow); // 直接启动户端,但网络线程呢???
#endif
Debug_Info("Davis, Free IWLDiagnose.dll, start\n");
FreeLibrary(hModule1);
Debug_Info("Davis, Free IWLDiagnose.dll, end\n");
}
Debug_Info("Davis, Free IWLConfClient.dll, start\n");
FreeLibrary(hModule);
Debug_Info("Davis, Free IWLConfClient.dll, end\n");
}
...
}
Q:难道非Diagnose模式就不启动这个网络子线程?