代码改变世界

windows线程创建

2012-10-11 15:03  kennyMc  阅读(394)  评论(0)    收藏  举报

ws中,线程是从所在进程的4GB地址空间中分配自己的栈。
线程内创建的局部变量都是在线程的栈上,静态或全家变量多个线程可以访问,容易破坏数据。

 

重要的一个知识点:线程的上下文context结构
之前在clr c#中看过,但是没有认真看,每个线程都有一组自己的CPU寄存器,叫做线程的上下文。
context结构保存了进程上次执行时CPU的寄存器状态。
当线程被调度到使用CPU时,系统用线程的上下文来初始化CPU的寄存器,其中一个CPU寄存器保存了

线程要执行的下一条CPU指令的地址,CPU寄存器中还有一个执行线程的栈地址的指针。

 

QQ截图20121011145244

 

#include <iostream>
#include <windows.h>
using namespace std;

//这个方法原型是定死的,还是NET中的线程方法写着方便
//参考:http://msdn.microsoft.com/en-us/library/ms686736(v=vs.85).aspx
DWORD WINAPI ThreadFun(PVOID param)
{
    int* par=(int*)param;
    *par=10;
    cout<<"ThreadFun par:"<<*par<<endl;
    return 0;
}

int main()
{
    //设置为静态变量防止ThreadFun违规访问销毁的变量
    static int x=0;
    DWORD dwThreadID;//线程ID
    //参考:http://msdn.microsoft.com/en-us/library/ms682453(VS.85).aspx
    HANDLE hThread=CreateThread(
        NULL,//SECURITY_ATTRIBUTES指针,设置NULL线程将获得一个默认的安全描述符
        0,//线程使用默认的大小为可执行文件(初始堆栈的大小)
        ThreadFun,//线程执行方法
        (PVOID)&x,//方法参数
        0,//标记,以控制线程的创建,0为该线程在创建后立即运行
        &dwThreadID);
    cout<<"main x:"<<x<<endl;//可能是0
    CloseHandle(hThread);
    cout<<"main x:"<<x<<endl;//可能是10
    system("PAUSE");
    return 0;
}

 

书上说创建线程应该用_beginthreadex,对于_beginthreadex和CreateThread的差别不是很清楚,只是知道_beginthreadex对于c++运行库的东西能做到线程安全,以后对用c c++做线程熟悉了再去深入研究吧。Net就把这些完全包装了,所以做了这么久NET也对底层不清楚。

#include <iostream>
#include <process.h>
#include <windows.h>
using namespace std;

//传递多个参数定义了个结构
struct _ThreadParameters
{
    int p1;
    int p2;
};

//这个方法原型是定死的,还是NET中的线程方法写着方便
//参考:http://msdn.microsoft.com/en-us/library/kdzttdcb.aspx
unsigned __stdcall ThreadFun(void* par)
{
    _ThreadParameters* _tPars=(_ThreadParameters*)par;
    cout<<"p1+p2="<<_tPars->p1+_tPars->p2<<endl;
    return 0;
}

int main()
{
    //设置为静态变量防止ThreadFun违规访问销毁的变量
    int x=0;
    unsigned dwThreadID;//线程ID
    _ThreadParameters tPars;
    tPars.p1=10;
    tPars.p2=22;
    HANDLE hThread=(HANDLE)_beginthreadex(NULL,0,&ThreadFun,(void*)&tPars,0,&dwThreadID);
    CloseHandle(hThread);
    system("PAUSE");
    return 0;
}