Multi-Threads in COM

原创 2011年01月10日 14:30:00

by Alex Zhang

I am working on distributed  calculation for complex security’s pricing , which  multi-threads knowledge is crucial, so I write down some tips , notes , ticks here, it’s not academicals just a tracing for my process.

February 20th ,2009

1. Create Thread using Windows APIs

Syntax:

   1:  HANDLE CreateThread(
   2:    LPSECURITY_ATTRIBUTES lpThreadAttributes,  // pointer to security attributes
   3:    DWORD dwStackSize,                         // initial thread stack size
   4:    LPTHREAD_START_ROUTINE lpStartAddress,     // pointer to thread function
   5:    LPVOID lpParameter,                        // argument for new thread
   6:    DWORD dwCreationFlags,                     // creation flags
   7:    LPDWORD lpThreadId                         // pointer to receive thread ID
   8:  );
   9:  
Parameters: (From MSDN)
lpThreadAttributes[in, optional]

A pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is NULL, the thread gets a default security descriptor. The ACLs in the default security descriptor for a thread come from the primary token of the creator.

Windows XP/2000:  The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the creator. This behavior changed with Windows XP with SP2 and Windows Server 2003. For more information, see Remarks.

dwStackSize [in]

The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable. For more information, see Thread Stack Size.

lpStartAddress [in]

A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the thread. For more information on the thread function, see ThreadProc.

lpParameter [in, optional]

A pointer to a variable to be passed to the thread.

dwCreationFlags [in]

The flags that control the creation of the thread.

Value

Meaning

0

The thread runs immediately after creation.

CREATE_SUSPENDED
0×00000004

The thread is created in a suspended state, and does not run until the ResumeThread function is called.

STACK_SIZE_PARAM_IS_A_RESERVATION
0×00010000

The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the commit size.

Windows 2000:  The STACK_SIZE_PARAM_IS_A_RESERVATION flag is not supported.

lpThreadId [out, optional]

A pointer to a variable that receives the thread identifier. If this parameter is NULL, the thread identifier is not returned.

Return Value

If the function succeeds, the return value is a handle to the new thread.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Note that CreateThread may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is handled as an error exit for the thread’s process. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs).

Specially Show the “ThreadProc” Function Here:

DWORD WINAPI ThreadProc(LPVOID lpParameter); replacing ThreadProc with the name of the function.

2. Manage Thread

2.1 Resume Thread (From MSDN)

Decrements a thread’s suspend count. When the suspend count is decremented to zero, the execution of the thread is resumed.

Syntax
DWORD WINAPI ResumeThread(
  __in  HANDLE hThread
);
Parameters
hThread [in]

A handle to the thread to be restarted.

This handle must have the THREAD_SUSPEND_RESUME access right. For more information, see Thread Security and Access Rights.

Return Value

If the function succeeds, the return value is the thread’s previous suspend count.

If the function fails, the return value is (DWORD) -1. To get extended error information, call GetLastError.

2.3 Suspend Thread (From MSDN)

SuspendThread Function

Suspends the specified thread.

A 64-bit application can suspend a WOW64 thread using the Wow64SuspendThreadfunction.

Syntax
DWORD WINAPI SuspendThread(
  __in  HANDLE hThread
);
Parameters
hThread [in]

A handle to the thread that is to be suspended.

The handle must have the THREAD_SUSPEND_RESUME access right. For more information, see Thread Security and Access Rights.

Return Value

If the function succeeds, the return value is the thread’s previous suspend count; otherwise, it is (DWORD) -1. To get extended error information, use the GetLastErrorfunction.

2.4 Waiting for terminate (From MSDN)

Obviously if “ThreadProc”  hasn’t returned within 0.1 seconds then something is wrong, but that isn’t the point. The WaitForSingleObject() function solves this problem.

WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE,DWORD);

WaitForSingleObject() waits until either the thread has terminated or the timeout value provided in the second parameter has elapsed. For this function we need the handle of the thread. MSDN recommends that all handles are closed with the CloseHandle() function before the program terminates.

2.5 Terminate Threads

Syntax
BOOL WINAPI TerminateThread(
  __inout  HANDLE hThread,
  __in     DWORD dwExitCode
);
Parameters
hThread [in, out]

A handle to the thread to be terminated.

The handle must have the THREAD_TERMINATE access right. For more information, seeThread Security and Access Rights.

dwExitCode [in]

The exit code for the thread. Use the GetExitCodeThread function to retrieve a thread’s exit value.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, callGetLastError.

AHA! A link  http://msdn.microsoft.com/en-us/library/ms684847(VS.85).aspx is much more than copy and paste.

3.Utilities For Synchronization

As you know , Mutex, event , lock and semaphore are  for this, what we need to do is OO it. Luckily , the laborious have done this:

For Example (From http://www.relisoft.com/Win32/active.html):

Mutex:

   1:      class Mutex
   2:      {
   3:          friend class Lock; //grant Lock object full control rights
   4:      public:
   5:          Mutex () { InitializeCriticalSection (& _critSection); }
   6:          ~Mutex () { DeleteCriticalSection (& _critSection); }
   7:      private:
   8:          void Acquire ()
   9:          {
  10:              EnterCriticalSection (& _critSection);
  11:          }
  12:          void Release ()
  13:          {
  14:              LeaveCriticalSection (& _critSection);
  15:          }
  16:          
  17:          CRITICAL_SECTION _critSection;
  18:      };

Lock:

   1:  class Lock
   2:      {
   3:      public:
   4:          // Acquire the state of the semaphore
   5:          Lock ( Mutex & mutex )
   6:              : _mutex(mutex)
   7:          {
   8:              _mutex.Acquire();
   9:          }
  10:          // Release the state of the semaphore
  11:          ~Lock ()
  12:          {
  13:              _mutex.Release();
  14:          }
  15:      private:
  16:          Mutex & _mutex;
  17:      };
 

Event:

   1:      class Event
   2:      {
   3:      public:
   4:          Event ()
   5:          {
   6:              // start in non-signaled state (red light)
   7:              // auto reset after every Wait
   8:              _handle = CreateEvent (0, FALSE, FALSE, 0);
   9:          }
  10:          ~Event ()
  11:          {
  12:              CloseHandle (_handle);
  13:          }
  14:          // put into signaled state
  15:          void Release () { SetEvent (_handle); }
  16:          void Wait ()
  17:          {
  18:              // Wait until event is in signaled (green) state
  19:              WaitForSingleObject (_handle, INFINITE);
  20:          }
  21:          operator HANDLE () { return _handle; }
  22:      private:
  23:          HANDLE _handle;
  24:      };

Semaphore VS Mutex:

http://ju-kevin.spaces.live.com/blog/cns!907BD90CD611C0C7!221.entry?wa=wsignin1.0&sa=531454868

Thread:

       #define DCalc_Log  //

       #define QL_REQUIRE //

    class Thread
    {
    public:
        Thread ( unsigned ( __stdcall * pFun) (void* arg), void* pArg)
        {
            _handle = (HANDLE)CreateThread (
                0, // Security attributes
                0, // Stack size
                pFun,
                pArg,
                CREATE_SUSPENDED,
                &_tid);
            QL_REQUIRE(_handle!=0,"Creat Thread Failure");

            DCalc_Log("Creat Thread OK , tid=%d",_tid);
        }
        virtual ~Thread ()
        {
            DCalc_Log("Thread Release");

            HRESULT hRes(S_OK);
            GetExitCodeThread(_handle, (LPDWORD) &hRes);
            CloseHandle (_handle); 

            DCalc_Log("Thread %d exit code = %un",_tid, hRes);
        }
        void Resume ()
        {
            ResumeThread (_handle);
        }
        void WaitForDeath ()
        {
            WaitForSingleObject (_handle, INFINITE);
        }
    private:
        HANDLE      _handle;
        unsigned  _tid;
    };
    

4. Com Multi-Thread Model

    As of the application environment (COM DLL),  some knowledge about COM multi-thread model is important.

    see  FW:COM Multi-Thread Model

5. My Application

   Base Class:

   1:      class DCalcThread
   2:      {
   3:      public:
   4:          DCalcThread ()
   5:              : _thread (ThreadEntry, this)
   6:          {
   7:          }
   8:  
   9:          virtual void RunDCalc () = 0;    
  10:          virtual ~DCalcThread () {}
  11:  
  12:      protected:
  13:          struct COMEnvSetting 
  14:          {
  15:              COMEnvSetting()
  16:              {
  17:  //                ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  18:              }
  19:              ~COMEnvSetting()
  20:              {
  21:  //                ::CoUninitialize();
  22:              }
  23:          };
  24:          static unsigned __stdcall ThreadEntry (void *pArg)
  25:          {
  26:  //            COMEnvSetting _envSetter;
  27:              DCalcThread * pActive = (DCalcThread *) pArg;
  28:              pActive->RunDCalc();
  29:  
  30:              return 0;            
  31:          };
  32:          
  33:          int             _isDying;
  34:          Thread          _thread;
  35:      };

  Sub Classes:

    Sample subclass A:

   1:     #define  DCalc_Log  //
   2:      class DCalcCNPV: public DCalcThread
   3:      {
   4:      public:
   5:          DCalcCNPV();
   6:          ~DCalcCNPV();
   7:  
   8:          void RunDCalc ()
   9:          {
  10:              DCalc_Log("Calc NPV");
  11:          }
  12:      private:
  13:      };
  Sample subclass B:
   1:    #define DCalc_Log  //
   2:      class DCalcCNPV: public DCalcThread
   3:      {
   4:      public:
   5:          DCalcCNPV();
   6:          ~DCalcCNPV();
   7:  
   8:          void RunDCalc ()
   9:          {
  10:              DCalc_Log("Calc NPV");
  11:          }
  12:      private:
  13:      };
 
  

I type some links here , making up for the lost of my re-product:

http://www.relisoft.com/Win32/active.html

http://www.geocities.com/samuel_super_camel/MultiThreadingTutorial.htm

http://www.cs.rpi.edu/academics/courses/netprog/WindowsThreads.html

POSIX multi-threads programming

学了一门课,叫High performance computing。提高程序执行效率一个很重要的方法就是多线程编程。在Linux和其他POSIX的系统上可以通过多线程(threads)实现。出来课堂笔...
  • ipip247
  • ipip247
  • 2008年06月23日 02:48
  • 241

An example for Perl Multi-threads

#!perl     use   threads;         @domain   =   ("tom.com",   "chinadns.com",   "163.com",   "aol.co...
  • striker
  • striker
  • 2009年03月12日 15:08
  • 416

Python example of SSH in multi-threads

I need to execute commands on several remote servers at the same time via ssh. Writing shell script ...
  • Jenny_yu1025
  • Jenny_yu1025
  • 2012年06月07日 15:22
  • 1106

.com .com .com .com .com .com .com.com .com .com .com .com .com .com.com .com .com .com .com .com .c

.com .com .com .com .com .com .com .com .com .com .com .com .com .com.com .com .com .com .com .com ...
  • XiaoHu1234567890
  • XiaoHu1234567890
  • 2013年10月10日 09:34
  • 96

Programming in Java: Multi-threads and interface vs abstract class

1) What is the difference of sleep() and wait()? from: http://www.cnblogs.com/plmnko/archive/2010/...
  • Firehotest
  • Firehotest
  • 2016年03月17日 13:51
  • 268

COM编程精彩实例--COM对象

创建一个COM对象的简单过程: 1)调用COM API接口 ::CoCreateInstance(),可以直接调用或通过一个已经包装的c++类调用。这个调用需要指定两个ID,一个是要实例化的类的ID...
  • zang141588761
  • zang141588761
  • 2016年12月20日 15:28
  • 787

COM组件入门(一)

最近需要用到COM组件的知识,看了看COM编程指南,感觉还不错,把我的学习心得记录下来。这是我写...
  • davidsu33
  • davidsu33
  • 2014年08月13日 17:08
  • 1280

C#与DLL和COM的混合编程(2)-C#调用COM组件

C#调用COM组件这部分描述了在托管代码中调用COM组件的方法,现存的COM组件在托管代码中作为中间件或者独立的功能实体是很有价值的资源  向.NET Framework报露COM组件1. Impor...
  • Net_Ghost
  • Net_Ghost
  • 2006年06月17日 01:08
  • 5367

在javascript中使用com组件的方法

转载自:  http://dhailin.blog.163.com/blog/static/230738322011128102043880/     首先创建一个COM组件,插入一个双接口...
  • chenyujing1234
  • chenyujing1234
  • 2012年09月16日 15:18
  • 5390

【VS开发】这就是COM组件

[实例]这就是COM组件 时间 2012-02-21 10:49:15  CSDN博客 原文  http://blog.csdn.net/btwsmile/article/details/72...
  • LG1259156776
  • LG1259156776
  • 2016年04月09日 21:42
  • 2708
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Multi-Threads in COM
举报原因:
原因补充:

(最多只允许输入30个字)