进程创建和线程创建

创建进程

WIN32 API提供了CreateProcess函数,用来创建一个新的进程和它的主线程。

//CreateProcess函数原型
BOOL WINAPI CreateProcess(
  _In_opt_    LPCTSTR               lpApplicationName,
  _Inout_opt_ LPTSTR                lpCommandLine,
  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_        BOOL                  bInheritHandles,
  _In_        DWORD                 dwCreationFlags,
  _In_opt_    LPVOID                lpEnvironment,
  _In_opt_    LPCTSTR               lpCurrentDirectory,//工作目录
  _In_        LPSTARTUPINFO         lpStartupInfo,
  _Out_       LPPROCESS_INFORMATION lpProcessInformation
);

其中STARTUPINFO结构体信息,可以通过GetStartupInfo函数来填充,这样,父进程的STARTUPINFO结构体信息就可以用到子进程的创建上。

typedef struct _STARTUPINFO {
  DWORD  cb;
  LPTSTR lpReserved;
  LPTSTR lpDesktop;
  LPTSTR lpTitle;
  DWORD  dwX;
  DWORD  dwY;
  DWORD  dwXSize;
  DWORD  dwYSize;
  DWORD  dwXCountChars;
  DWORD  dwYCountChars;
  DWORD  dwFillAttribute;
  DWORD  dwFlags;
  WORD   wShowWindow;
  WORD   cbReserved2;
  LPBYTE lpReserved2;
  HANDLE hStdInput;
  HANDLE hStdOutput;
  HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
VOID WINAPI GetStartupInfo(
  _Out_ LPSTARTUPINFO lpStartupInfo
);

dwCreationFlags参数用于设置进程的创建模式和优先级。
其中进程的创建标志详见:

Process Creation Flags
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx

优先级标志详见:

GetPriorityClass function
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683211(v=vs.85).aspx

优先级由高到低为:IDLE_PRIORITY_CLASS,BELOW_NORMAL_PRIORITY_CLASS,NORMAL_PRIORITY_CLASS,ABOVE_NORMAL_PRIORITY_CLASS,HIGH_PRIORITY_CLASS,REALTIME_PRIORITY_CLASS。

创建线程

WIN32 API提供了CreateThread函数,用来创建一个新线程。

//CreateThread函数原型
HANDLE WINAPI CreateThread(
  _In_opt_  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  _In_      SIZE_T                 dwStackSize,
  _In_      LPTHREAD_START_ROUTINE lpStartAddress,
  _In_opt_  LPVOID                 lpParameter,
  _In_      DWORD                  dwCreationFlags,
  _Out_opt_ LPDWORD                lpThreadId
);

其中lpThreadAttributes指向一个SECURITY_ATTRIBUTES,该结构体声明如下。其中nLength设置为sizeof(SECURITY_ATTRIBUTES),lpSecurityDescriptor指向一个SECURITY_DESCRIPTOR结构体,设置为NULL则子线程会沿用父线程的ACL,bInheritHandle指定创建的线程的句柄可否被继承。
在调用CreateThread时该函数可以置NULL,意味沿用父进程的ACL并且句柄不可被继承。

typedef struct _SECURITY_ATTRIBUTES {
  DWORD  nLength;
  LPVOID lpSecurityDescriptor;
  BOOL   bInheritHandle;
}SECURITY_ATTRIBUTES,*PSECURITY_ATTRIBUTES,*LPSECURITY_ATTRIBUTES;

dwStackSize参数设置线程的栈大小,设置为0会使用一个系统默认的栈大小。
lpStartAddress参数指向线程的运行函数地址。该线程运行函数应和以下函数原型相符。

DWORD WINAPI ThreadProc(
  _In_ LPVOID lpParameter
);

lpParameter参数就是希望传递给线程运行函数的参数,如果希望传递多个参数,可以以结构体的形式,将结构体指针作为void*传递。
dwCreationFlags参数可以设置线程创建后是立即运行还是挂起。0表示立即运行,CREATE_SUSPENDED表示创建后挂起线程。
lpThreadId参数是个输出参数,用于接受线程id。
返回值是一个句柄,如果线程创建成功,返回线程句柄,如果失败返回NULL,调用GetLastError获得错误信息。

上面讲到的是WIN32提供的API函数,而MFC也提供了创建线程的函数,虽然本质上也是通过调用WIN32 API函数CreateThread实现的,但是为用户封装了许多操作,提供了现成的功能,例如消息循环等。

MFC提供的线程创建

//AfxBeginThread函数原型
CWinThread* AfxBeginThread(
   AFX_THREADPROC pfnThreadProc,
   LPVOID pParam,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 
);
CWinThread* AfxBeginThread(
   CRuntimeClass* pThreadClass,
   int nPriority = THREAD_PRIORITY_NORMAL,
   UINT nStackSize = 0,
   DWORD dwCreateFlags = 0,
   LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL 
);

第一个AfxBeginThread用于创建工作线程,参数根据形参英文简单明了,不说太多。在MFC中,创建工作线程会构造一个CWinThread对象(与UI线程使用的CWinThread构造函数不同),并调用CWinThread::CreateThread创建线程,之后直接进入线程函数而不进入run()消息循环。
第二个AfxBeginThread用于创建UI线程,创建方法大致如下:
1.从CWinThread派生一个自己的CUIThread类。
2.在CUIThread类中重载InitInstance函数,创建自己界面之类云云,此处要注意设置CWinThread::m_hMainWnd成员,不然线程不会随着窗口关闭而结束。(工作线程的CWinThread::m_hMainWnd成员会直接继承父线程的)
3.调用AfxBeginThread(RUNTIME_CLASS(CUIThread))启动线程。

你可能感兴趣的:(C++,创建进程,创建线程,UI线程,工作线程,MFC线程)