1.什么是线程?
- 线程是附属在进程上的执行实体,是代码的执行流程.
- 一个进程可以包含多个线程,但一个进程至少要包含一个线程.
进程是空间的概念,挂起进程,实际上是挂起线程.
线程是时间的概念.
线程有多少个,说明有多少个代码段在执行
怎么理解多个代码段在执行?
并不一定是同时执行.
- 单核状态下,是线程交叉执行的,感觉这个俩个线程同时执行(受限于CPU 和寄存器)
- 多核的情况下,多个CPU同时进行跑线程
2.创建线程
HANDLE CreateThread(
lpSECURITY_ATTBUTES lpThreadAttributes //SD 只要是内核对象,有会有SD 安全描述符
SIZE_T dwStackSIze, //initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, //thread function 其实就是填入函数的地址
LPVOID lpParameter, //thread argument
DWORD dwCreationFlags, //creation option
LPDWORD lpThreadId //[OUT] thread identifier
)
无参 创建线程
#include "stdafx.h"
#include <Windows.h>
//花式使用线程函数
VOID __stdcall testProc(){
for(int i = 100 ;i > 0;i--){
Sleep(500);
printf("++++++++ %d \n",i);
}
}
//WINAPI __stdcall 外平栈
DWORD WINAPI ThreadProc(LPVOID lpParameter){
for(int i = 100 ;i > 0;i--){
Sleep(500);
printf("++++++++ %d \n",i);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread;
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)testProc,NULL,0,NULL);
CloseHandle(hThread);//count-- 关闭线程的俩个必要条件:1.线程代码执行完成 2.线程内核对象计数器 == 0
for(int i = 100 ;i > 0;i--){
Sleep(500);
printf("--------%d \n",i);
}
return 0;
}
有参 创建进程
#include "stdafx.h"
#include <Windows.h>
//花式使用线程函数
VOID __stdcall testProc(){
for(int i = 100 ;i > 0;i--){
Sleep(500);
printf("++++++++ %d \n",i);
}
}
//WINAPI __stdcall 外平栈
DWORD WINAPI ThreadProc(LPVOID lpParameter){
for(int i = 100 ;i > 0;i--){
Sleep(500);
printf("++++++++ %d \n",i);
}
return 0;
}
struct Para{
int num;
char* name;
};
DWORD WINAPI ThreadProc2(LPVOID lpParameter){
Para* para = (Para*)lpParameter;
//printf("para.num %d",para->num);
for(int i = para->num ;i > 0;i--){
Sleep(500);
printf("%s ++++++++ %d \n",para->name,i);
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hThread;
//无参数 创建线程
//hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)testProc,NULL,0,NULL);
//有参数创建线程
Para para;
para.num = 10;
char* name = "chenjiale";
para.name = name;
//printf("%s",para.name);
CreateThread(0,0,ThreadProc2,¶,0,0);
//CloseHandle(hThread);//count-- 关闭线程的俩个必要条件:1.线程代码执行完成 2.线程内核对象计数器 == 0
for(int i = 5 ;i > 0;i--){
Sleep(500);
printf("--------%d \n",i);
}
//getchar();
return 0;
}
创建线程的参数,实际上可以传入任何一块内存,可以是任何类型,传进去的是一个地址,这个地址存了参数的值.
还要注意一点:主要线程的生命周期应该要比 ,子线程的生命周期长,这样才能保证程序正常执行.因为子线程在创建的时候如果没标识堆栈,那么会默认使用caller的堆栈,如果子线程还在运行,caller却已经运行完成了,那么子线程的堆栈会丢失,子线程的参数也没了. 所以一般把子线程的参数放在全局变量,生命周期一直在