#include
#include
DWORD WINAPI ThreadProc( LPVOID lpParameter);
int main (void)
{
for (BYTE i=0;i<5;i++)
{
DWORD IDThread=0;
HANDLE hThread=CreateThread(NULL,NULL,ThreadProc,(LPVOID)i,NULL,&IDThread);
if (hThread)
CloseHandle(hThread);
}
getchar();
return 0;
}
DWORD WINAPI ThreadProc( LPVOID lpParameter)
{
for (BYTE i=0;i<10;i++)
{
printf("%d---%d---%d---%d\n",lpParameter,lpParameter,lpParameter,lpParameter);
Sleep(1);
}
return true;
}
/*
CPU一次执行一行代码,在main函数中创建了4个线程,调用同一个函数。
在4个线程同时执行的时候,发生CPU时间片切换,在ThreadProc函数中执行的代码可能不一样
我的意思是线程1中的局部变量被改写,不会影响线程2中的局部变量。
那4个线程同时执行一个函数,那这个函数被拷贝到每个线程的内部去执行了?咋感觉理解起来很抽象
*/
函数不存在拷贝不拷贝的。
好比你电脑上同时运行2个word,并不需要拷贝2份代码。
每个程序之所以独立运行,只要它们的数据是独立的就可以。
具体来说,程序的数据分为寄存器、堆栈、堆、静态存储(只读,可以无视)几个部分
多进程程序,每个程序有自己的寄存器、堆栈、堆,所以完全独立
同一个程序的多线程,只有寄存器和堆栈是独立的,堆是共享的,也就是那些new出来的对象以及全局变量,这些需要同步。
程序在cpu轮换的时候,会通过一个线程上下文的结构保存当前的线程的当前状态的寄存器。同时将另一个线程的寄存器的状态(保存在线程上下文中)恢复到寄存器里。
而寄存器中某一个(esp)会指向这个线程的堆栈,另一个(eip)会指向当前执行的指令,有了它们程序就可以继续执行了。被恢复了的进程因此感觉不到自己被暂停过,仿佛自己是连续运行的一样。
另外,现在的计算机往往不止一个处理器,那么这种情况计算机内每个处理器都有自己的寄存器,也都可以平行执行程序,而不需要轮换。
线程函数的变量都是局部变量,在线程函数所在栈桢给空间。线程切换,就一起切换了,不会干扰,只有全局变量,或其它线程共享数据就可能在线程切换的时候还能访问到,这就是线程安全需要考虑的,防止这样的数据在多个线程之间被改坏,出现数据错误。
就这个图,自己看看就理解了。进程空间中的变量和线程空间中的变量存在不同的地方。
这个涉及到变量的作用域,函数里面的局部变量一直都是出了函数就不能使用了。线程都是基于函数来运行,所以里面的局部变量都是独立的。而成员变量,静态变量等就不一样了。