C++多线程使用笔记

头文件 : process.h
运行环境 : Windows

创建线程函数

1
2
3
4
5
6
7
8
unsigned long _beginthreadex(
void *security,
unsigned stack_size,
unsigned (__stdcall *start_address)(void*),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);
  • 第一个参数 security : 安全属性,默认为NULL
  • 第二个参数 stack_size : 指定线程堆栈大小;若为0则和创建它的线程相同
  • 第三个参数 start_address : 指定线程函数的地址,即线程调用执行的函数地址
  • 第四个参数 arglist : 传递给线程函数的参数的指针(调用时转为void指针,可在线程函数中在转化成对应类型指针)
  • 第五个参数 initflag : 线程初始状态;0 : 立即运行;CREATE_SUSPEND : 悬挂
  • 第六个参数 thrdaddr : 用于记录线程ID的地址,可为0

该函数返回一个新线程的句柄(HANDLE)

线程(处理)函数

  • 函数返回类型 : unsigned __stdcall
  • 函数参数 : void* 型指针

退出线程

  • 线程函数正常返回(一般使用的方法) : 能安全回收该线程的处理器资源和内存资源
  • 调用 _endthreadex() 或 ExitThread() 函数,线程自行撤销
  • 调用 TerminateThread() 函数(避免使用)
  • 终止线程所在进程(避免使用)

windows还提供了一些库函数用来获得当前进程或者线程的句柄, 如 HANDLE GetCurrentProcess() 函数返回当前进程的句柄, HANDLE GetCurrentThread() 函数返回当前线程的句柄, 但是需要注意的是, 这些句柄都是 ‘伪句柄’ , 即: 只在本进程和本线程内可用, 不可传出取用。
如果需要在外部使用其它线程或进程的句柄, 则可以用 DuplicateHandle(…) 函数获得其它进程或者线程的 ‘实句柄’ , 该函数接受7个参数, 具体的用法可以查阅一下msdn和网络. 需要注意的是, 在使用完 由DuplicateHandle(…) 函数获得的句柄后, 需要使用 CloseHandle() 函数来关闭该句柄。
来源 http://www.cnblogs.com/zhuocheng/archive/2011/10/02/2198310.html

等待线程退出

1
2
3
4
5
6
DWORD WaitForMultipleObjects(
DWORD nCount, // number of handles in the handle array
CONST HANDLE *lpHandles, // pointer to the object-handle array
BOOL fWaitAll, // wait flag
DWORD dwMilliseconds // time-out interval in milliseconds
);
  • 该函数可以等待Windows中几乎一切内核对象
  • nCount最大值为MAXIMUM_WAIT_OBJECTS(64)
  • lpHandles所指HANDLE类型可以为(Event, Mutex, Process, Thread, Semaphore)数组
  • fWaitAll为TRUE,除非对象都发出信号,否则就一直等待下去;为FALSE,表示任何对象发出信号即可
  • dwMilliseconds为0,立即返回
1
2
3
4
DWORD WaitForSingleObject(
HANDLE hObject,
DWORD dwMilliseconds
);
  • 对于第二个参数,INFINITE定义为无限时间量(0xFFFFFFFF)

Windows中线程为内核对象,最后需要CloseHandle
C++主线程的终止,同时也会终止所有主线程创建的子线程(子线程可能没有执行完毕或没有执行)
等待挂起进程会导致死锁
来源 : http://www.cppblog.com/mzty/archive/2007/07/25/28756.html


一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <process.h>
unsigned __stdcall threadFunc(void*) {
//...
// _endthreadedx(0);
return 0;
}
int main() {
HANDLE hThread;
unsigned int threadID;
// 创建线程
hThread = (HANDLE)_beginthreadex(NULL, 0, (void*)&threadFunc, NULL, 0, &threadID);
// ...
WaitForSingleObject(hThread, INFINITE);
// WaitForMultipleObjects(clntCount, hThread, TRUE, INFINITE);
// 销毁线程
CloseHandle(hThread);
return 0;
}