http://www.cnblogs.com/wParma/archive/2009/10/30/1593002.html
线程定义
• 一个是线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。
• 另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量(第1 6章将进一步介绍系统如何管理线程堆栈)。
如何创建线程:
HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa,
//安全结构体如果希望内核对象能被子进程继承必须将b I n h e r i t H a n d l e成员被初始化为T R U E
DWORD cbStack,
//线程堆栈大小
PTHREAD_START_ROUTINE pfnStartAddr,
//线程函数地址
PVOID pvParam,
//线程参数地址
DWORD fdwCreate,
//创建标示(是否立即执行在这指定)
PDWORD pdwThreadID
//线程ID );
线程创建时发生了什么:
基于C/C++运行库的线程创建函数
unsigned long _beginthreadex(
void *security,
unsigned stack_size,
unsigned *start_address)(void *),
void *arglist,
unsigned initflag,
unsigned *thrdaddr);
此函数为每个线程单独分配数据块解决了一部分问题,其实也是在内部调用CreateThread来实现创建新线程的,只不过在应当传递线程函数地址的地方传递了_threadstartex,在应该传递线程参数的地方传递了(PVOID)ptd。看一下_threadstartex的伪码此函数为每个线程单独分配数据块解决了一部分问题,其实也是在内部调用CreateThread来实现创建新线程的,只不过在应当传递线程函数地址的地方传递了_threadstartex,在应该传递线程参数的地方传递了(PVOID)ptd。看一下_threadstartex的伪码
static unsigned long WINAPI threadstartex (void* ptd){
//Note:ptd is the address of this thread's tiddata block.
//Associate the tiddata block with this thread.
TlsSetValue(__tlsindex, ptd);
//Save this thread ID in the tiddata block.
((_ptiddata)ptd)->_tid = GetCurrentThreadId();
//Initialize floating-point support (code not shown).
//wrap desired thread function in SEH frame to
//handle run-time errors and signal support.
__try {
//Call desired thread function, passing it the desired parameter.
//Pass thread's exit code value to _endthreadex.
_endthreadex(
((unsigned(WINAPI *)(void *))(((_ptiddata)ptd)->_initaddr))
(((_ptiddata)ptd)->_initarg));
}
__except(_XcptFilter(GetExceptionCode(), GetExceptionInformation()))
{
//The C run-time's exception handler deals with run-time errors
//and signal support; we should never get it here.
_exit(GetExceptionCode()); }
//We never get here; the thread dies in this function.
return(0L);
}
注意到这里((unsigned(WINAPI *)(void *))(((_ptiddata)ptd)->_initaddr))(((_ptiddata)ptd)->_initarg));