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

相关文章推荐

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 ...

Java multi-threads to read DB then writting to local disk with Producer & Consumer model

There will be several Producers to access DB and put result into list; only one Consumer will access...

Understand Threads in python

We will see some examples of using threads in Python and how to avoid race conditions: You should...

Threads and Anonymous Classes in JAVA

As we all know,a thread is a separate process on your computer.you can run multiple threads all at t...

C++11 多线程编程《C++ Concurrency in Action》读书笔记(3)-Sharing data between Threads

1.1     Problems with sharingdata between threads When it comes down to it, the problems withsharin...

Linux Kernel Threads in Device Drivers

Purpose This examples shows how to create and stop a kernel thread. Thedriver is implemented as a ...

Synchronizing threads in Java

The nice thing about threads in Java is that they are always there. This has hindered the porting of...

Processes and Threads in android

转自   译者署名: 呆呆大虾 译者微博: http://weibo.com/popapa 版本:Android 3.2 r1   进程和线程 如果某个应用程序组件是第一次被启动,且...
  • lpplou
  • lpplou
  • 2012年04月23日 09:47
  • 475

Threads and Pipes in Console Apps

  • 2009年06月18日 10:12
  • 162KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Multi-Threads in COM
举报原因:
原因补充:

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