第一部分代码 CreateThread();
线程传值线程返回pid
#include <Windows.h> #include <iostream> //传值 返回进程id DWORD WINAPI ThreadFun(LPVOID pm) { std::cout<<*((int*)pm)<<"\nhello world!!!\n"<<GetCurrentThreadId()<<std::endl; return 0; } int main() { printf("最简单的创建多线程实例\n"); DWORD m=NULL; int* x=new int(13); HANDLE handler =CreateThread(NULL,0,ThreadFun,x,0,&m); WaitForSingleObject(handler,INFINITE); printf("进程ID为%d\n",m); system("pause"); delete x; return 0; }
此段内容复制的
_beginthreadex()函数在创建新线程时会分配并初始化一个_tiddata块。这个_tiddata块自然是用来存放一些需要线程独享的数据。事实上新线程运行时会首先将_tiddata块与自己进一步关联起来。然后新线程调用标准C运行库函数如strtok()时就会先取得_tiddata块的地址再将需要保护的数据存入_tiddata块中。这样每个线程就只会访问和修改自己的数据而不会去篡改其它线程的数据了。因此,如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread()。
第二段代码:_beginthreadex()
#include <iostream> #include<Windows.h> #include <process.h> unsigned int __stdcall ThreadFun(PVOID pm) { std::cout<<GetCurrentThreadId()<<"说:"<<*((int*)pm)<<std::endl; return 0; } int main() { const int n =5; int x[n]={0,9,8,7,6}; unsigned int a[n]; HANDLE handle[n]; for(int i=0;i<n;i++) handle[i] =(HANDLE)_beginthreadex(NULL,0,ThreadFun,&x[i],0,&a[i]); WaitForMultipleObjects(n,handle,true,INFINITE); for(int j=0;j<n;j++) std::cout<<a[j]<<std::endl; system("pause"); return 0; }
运行结果:
这张图好不容易截到;充分说明进程调用过程的不确定性