CreateProcess函数创建了线程,每个进程至少有一个主线程,这个线程从入口地址main开始执行,直到return语句返回,主线程结束,进程从内存中卸载。
主线程可在运行过程中创建新的线程,即多线程。同一进程中的多线程的好处是这些线程可以共享进程的资源,如全局变量、句柄。当然各线程也可以用自己的私有堆栈保存私有数据。
要在主线程中创建一个辅助线程,必须为该辅助线程指定一个入口点函数,这个函数称为线程函数。线程函数定义如下
DWORD WINAPI ThreadProc(LPVOID lpParam); //线程函数名称ThreadProc可以自定义
参数lpParam的值由CreateThread函数的第四个参数决定;
///////////////////////////////////////////////////////////////
// ThreadDemo.cpp文件
#include <stdio.h>
#include <windows.h>
// 线程函数
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
int i = 0;
while(i < 20)
{
printf(" I am from a thread, count = %d \n", i++);
}
return 0;
}
int main(int argc, char* argv[])
{
HANDLE hThread;
DWORD dwThreadId;
// 创建一个线程
hThread = ::CreateThread (
NULL, // 默认安全属性
NULL, // 默认堆栈大小
ThreadProc, // 线程入口地址(执行线程的函数)
NULL, // 传给函数的参数
0, // 指定线程立即运行
&dwThreadId); // 返回线程的ID号
printf(" Now another thread has been created. ID = %d \n", dwThreadId);
// 等待新线程运行结束
::WaitForSingleObject (hThread, INFINITE);
::CloseHandle (hThread);
return 0;
}
函数名前的双冒号表示这是windows api的全局函数
WaitForSingleObject函数用于等待特定的对象(如hThread)变成受信状态,受信状态指的线程运行结束后,才会继续向下运行
===============================
*.线程的内核对象
它是一个包含线程状态信息的数据结构,每成功调用一次CreadThread函数,都会在系统内部为新的线程分配一个内核对象。系统提供的管理线程的函数其实就是依靠访问线程内核对象来实现管理的
它分为:线程上下文,使用计数,暂停次数,退出代码,是否受信
线程上下文是一组CPU寄存器,反应了线程运行时的CPU寄存器状态(按我的理解就是反应了线程起始处的内存是什么样的,方便线程结束后还原)
使用计数初始是2,使用CloseHandle函数关闭只会减去1,是关不掉的,只有线程结束后减去1,再关又减去1,才能关闭
线程只有暂停次数为0时才能被cpu调度,暂停可多次,恢复时也要恢复多次,大约每20ms,系统查看一次所有线程内核对象,当发现了可调度的内核对象后,将其上下文装入cpu寄存器,这一过程称为上下文转换。不过这么干的前提是这些可调度的线程具有相同的优先级,而现实中几乎所有的线程优先级都不一样。
退出代码规定的是线程函数的返回值,这个值在线程还没退出时值是固定的STILL_ACTUVE,线程结束后被系统设置为线程函数的返回值,所以根据这点,用函数GetExitCodeThread取得该值判断线程是否已经结束
线程在运行时是不可受信,只有结束后才会才会变为可受信状态
========================
优先级:优先级号取值为0-31,31最高,最高的那个永远优先被调度,除非他暂时无法被调度,系统就会依照顺序调度其它的低优先级