浅析继承omni_thread类的所有子类都怎样创建运行子类线程
1.实现virtual run方法作为omni_thread_wrapper线程执行时的run函数
以下子类使用了该run方法:
class vncClientThread
class vncTimedMsgBoxThread
对象 = new 子类;
在new子类时将调用omni_thread父类如下构造函数
omni_thread::omni_thread(void* arg, priority_t pri)
{
common_constructor(arg, pri, 1);
// 这样在omni_thread_wrapper线程中将调用子类::run方法[luther.gliethttp]
// 子类::run
fn_void = NULL;
fn_ret = NULL;
}
==>omni_thread::start
==>创建omni_thread_wrapper线程毁掉函数
==>子类::run()
vncService::InstallService
==>vncTimedMsgBox::Do(
"The WinVNC service was successfully installed\n"
"The service will start now and will automatically\n"
"be run the next time this machine is reset",
szAppName,
MB_ICONINFORMATION | MB_OK);
==>vncTimedMsgBox::Do(
"The WinVNC service was successfully installed\n"
"The service may be started from the Control Panel, and will\n"
"automatically be run the next time this machine is reset",
szAppName,
MB_ICONINFORMATION | MB_OK);
vncService::RemoveService()
==>vncTimedMsgBox::Do("The WinVNC service has been removed", szAppName, MB_ICONINFORMATION | MB_OK);
==>vncTimedMsgBox::Do("The WinVNC service has been removed", szAppName, MB_ICONINFORMATION | MB_OK);
class vncTimedMsgBox
{
public:
// Bring up a message box, wait for two seconds, then return
static void Do(const char *caption, const char *title, UINT type); // 定义类方法[luther.gliethttp]
};
void
vncTimedMsgBox::Do(const char *caption, const char *title, UINT type)
{
// Create the thread object
vncTimedMsgBoxThread *thread = new vncTimedMsgBoxThread(caption, title, type);
/*
父类将执行如下构造函数
omni_thread::omni_thread(void* arg, priority_t pri)
{
common_constructor(arg, pri, 1);
// 这样在omni_thread_wrapper线程中将调用子类的vncTimedMsgBoxThread::run方法[luther.gliethttp]
// vncTimedMsgBox::run
fn_void = NULL;
fn_ret = NULL;
}
*/
if (thread == NULL)
return;
// Start the thread object
thread->start();
// 调用omni_thread::start()方法创建omni_thread_wrapper线程
// And wait a few seconds
Sleep(TIMED_MSGBOX_DELAY);
}
class vncTimedMsgBoxThread : public omni_thread // vncTimedMsgBoxThread类继承自omni_thread
{
public:
vncTimedMsgBoxThread(const char *caption, const char *title, UINT type)
{
m_type = type;
m_caption = strdup(caption);
m_title = strdup(title);
};
virtual ~vncTimedMsgBoxThread()
{
if (m_caption != NULL)
free(m_caption);
if (m_title != NULL)
free(m_title);
};
virtual void run(void *)
{
// Create the desired dialog box
if (m_caption == NULL)
return;
MessageBox(NULL, m_caption, m_title, m_type | MB_OK);
};
char *m_caption;
char *m_title;
UINT m_type;
};
2.实现virtual run_undetached方法作为omni_thread_wrapper线程执行时的run_undetached函数
以下子类使用了该run_undetached方法:
class vncDesktopThread
class vncHTTPConnectThread
class vncSockConnectThread
对象 = new 子类;
在new子类时将调用omni_thread父类如下构造函数
omni_thread::omni_thread(void* arg, priority_t pri)
{
common_constructor(arg, pri, 1);
// 这样在omni_thread_wrapper线程中将调用子类::run方法[luther.gliethttp]
fn_void = NULL;
fn_ret = NULL;
}
==>omni_thread::start_undetached
==>detached = 0; // 标识omni_thread_wrapper线程不执行子类::run函数,而执行子类::run_undetached方法[luther.gliethttp]
==>omni_thread::start
==>创建omni_thread_wrapper线程毁掉函数
==>子类::run_undetached
比如:
class vncSockConnectThread : public omni_thread
{
public:
// Init routine
virtual BOOL Init(VSocket *socket, vncServer *server);
// Code to be executed by the thread
virtual void *run_undetached(void * arg); // 覆盖父类omni_thread的run_undetached方法
......
}
m_thread = new vncSockConnectThread;
==>((vncSockConnectThread *)m_thread)->Init(&m_socket, server);
BOOL vncSockConnectThread::Init(VSocket *socket, vncServer *server)
{
// Save the server pointer
m_server = server;
// Save the socket pointer
m_socket = socket;
// Start the thread
m_shutdown = FALSE;
start_undetached(); // 执行父类omni_thread的start_undetached方法
return TRUE;
}
void
omni_thread::start_undetached(void)
{
if ((fn_void != NULL) || (fn_ret != NULL))
throw omni_thread_invalid();
detached = 0; // 这样omni_thread::detached = 0;
start();
}
3.构造一个类,指定void (*fn)(void*)形式作为omni_thread线程中执行函数
WinMain
==>if (strncmp(&szCmdLine[i], winvncRunService, strlen(winvncRunService)) == 0)
{
// Run WinVNC as a service
return vncService::WinVNCServiceMain();
}
==>vncService::WinVNCServiceMain
==>对于Windows NT操作系统
SERVICE_TABLE_ENTRY dispatchTable[] = {
{VNCSERVICENAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain}, // 创建函数
{NULL, NULL}
};
==>omni_thread *workthread = omni_thread::create(ServiceWorkThread);
omni_thread*
omni_thread::create(void (*fn)(void*), void* arg, priority_t pri)
{
omni_thread* t = new omni_thread(fn, arg, pri);
t->start();
return t;
}
omni_thread::omni_thread(void (*fn)(void*), void* arg, priority_t pri)
{
common_constructor(arg, pri, 1);
fn_void = fn;
fn_ret = NULL;
}
4.构造一个类,指定void* (*fn)(void*)形式作为omni_thread线程中执行函数
vncService::SimulateCtrlAltDel // 按下ctrl+alt+del组合键之后
==>omni_thread *thread = omni_thread::create(SimulateCtrlAltDelThreadFn);
omni_thread*
omni_thread::create(void* (*fn)(void*), void* arg, priority_t pri)
{
omni_thread* t = new omni_thread(fn, arg, pri);
t->start();
return t;
}
omni_thread::omni_thread(void* (*fn)(void*), void* arg, priority_t pri)
{
common_constructor(arg, pri, 0);
fn_void = NULL;
fn_ret = fn;
}
///////////////////////////////////////////////////////////////
omni_thread::start(void)
{
handle = (HANDLE)_beginthreadex(
NULL,
0,
omni_thread_wrapper, // 创建线程
(LPVOID)this,
CREATE_SUSPENDED,
&t);
SetThreadPriority(handle, _priority);
ResumeThread(handle); // 启动线程函数omni_thread_wrapper执行
}
线程回调函数omni_thread_wrapper实现部分代码
extern "C"
#ifndef __BCPLUSPLUS__
unsigned __stdcall
#else
void _USERENTRY
#endif
omni_thread_wrapper(void* ptr)
{
omni_thread* me = (omni_thread*)ptr;
DB(cerr << "omni_thread_wrapper: thread " << me->id()
<< " started\n");
if (!TlsSetValue(self_tls_index, (LPVOID)me))
throw omni_thread_fatal(GetLastError());
//
// Now invoke the thread function with the given argument.
//
if (me->fn_void != NULL) {
(*me->fn_void)(me->thread_arg); // 运行指定函数
omni_thread::exit(); // 退出线程
}
if (me->fn_ret != NULL) {
void* return_value = (*me->fn_ret)(me->thread_arg); // 运行指定函数
omni_thread::exit(return_value); // 退出线程
}
if (me->detached) {
me->run(me->thread_arg);
// 执行该方法子类重新实现函数vncClientThread::run();
// 执行该句,对me->detached的赋值见上面::omni_thread构造函数
omni_thread::exit();
} else {
void* return_value = me->run_undetached(me->thread_arg);
// 执行该方法子类重新实现函数vncSockConnectThread::run_undetachedme->thread_arg();
// vncSockConnectThread执行到这里,
// 因为omni_thread::start_undetached()方法设置omni_thread::detached = 0;
// 对该赋值操作分析见上面[luther.gliethttp]
omni_thread::exit(return_value);
}
// should never get here.
#ifndef __BCPLUSPLUS__
return 0;
#endif
}
|