Chinaunix首页 | 论坛 | 博客
  • 博客访问: 13334623
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22365
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: WINDOWS

2009-05-31 18:08:30

浅析继承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
}

阅读(2257) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~